Skip to content

Commit 2662d30

Browse files
authored
Forms: fix attribute appender (#45999)
* changelog * replace use of preg_replace with parse_blocks and serialize_blocks * add tests, but malformed JSON objects on attributes can still be a problem * update tests and attend to phan complaints * move tests for grunion_contact_form_apply_block_attribute to Util_Test * refactor grunion_contact_form_apply_block_attribute test to use provider function, not much improvement, but use the same provider approach consistently
1 parent 5d611d6 commit 2662d30

File tree

4 files changed

+668
-218
lines changed

4 files changed

+668
-218
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Significance: patch
2+
Type: added
3+
4+
Forms: use parse_blocks instead of preg_replace for attribute appending on templates and widgets

projects/packages/forms/src/contact-form/class-util.php

Lines changed: 38 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -398,35 +398,45 @@ public static function grunion_contact_form_apply_block_attribute( $content, $ne
398398
if ( false === stripos( $content, 'wp:jetpack/contact-form' ) ) {
399399
return $content;
400400
}
401-
return preg_replace_callback(
402-
'/<!--\s+(?P<closer>\/)?wp:jetpack\/?contact-form\s+(?P<attrs>{(?:(?:[^}]+|}+(?=})|(?!}\s+\/?-->).)*+)?}\s+)?(?P<void>\/)?-->/s',
403-
function ( $match ) use ( $new_attr ) {
404-
// Ignore block closers.
405-
if ( ! empty( $match['closer'] ) ) {
406-
return $match[0];
407-
}
408-
// If block doesn't have attributes, add our own.
409-
if ( empty( $match['attrs'] ) ) {
410-
return str_replace(
411-
'wp:jetpack/contact-form ',
412-
'wp:jetpack/contact-form ' . wp_json_encode( $new_attr ) . ' ',
413-
$match[0]
414-
);
415-
}
416-
$attrs = json_decode( rtrim( $match['attrs'], ' ' ), true );
417-
// Ensure $attrs is an array before merging (json_decode can return null on invalid JSON).
418-
if ( ! is_array( $attrs ) ) {
419-
$attrs = array();
420-
}
421-
$attrs = array_merge( $attrs, $new_attr );
422-
return str_replace(
423-
$match['attrs'],
424-
wp_json_encode( $attrs ) . ' ',
425-
$match[0]
401+
402+
// Parse blocks using WordPress core function.
403+
$blocks = parse_blocks( $content );
404+
405+
// Recursively modify contact form blocks.
406+
$modified_blocks = self::modify_contact_form_blocks_recursive( $blocks, $new_attr );
407+
408+
// Serialize back to block markup.
409+
return serialize_blocks( $modified_blocks );
410+
}
411+
412+
/**
413+
* Recursively modifies contact form blocks to add new attributes.
414+
*
415+
* @param array $blocks Array of parsed blocks.
416+
* @param array $new_attr New attributes to add.
417+
* @return array Modified blocks array.
418+
*/
419+
private static function modify_contact_form_blocks_recursive( $blocks, $new_attr ) {
420+
foreach ( $blocks as &$block ) {
421+
// Check if this is a contact form block.
422+
if ( 'jetpack/contact-form' === $block['blockName'] ) {
423+
// Merge new attributes with existing ones.
424+
$block['attrs'] = array_merge(
425+
$block['attrs'] ?? array(),
426+
$new_attr
426427
);
427-
},
428-
$content
429-
);
428+
}
429+
430+
// Recursively process inner blocks.
431+
if ( ! empty( $block['innerBlocks'] ) ) {
432+
$block['innerBlocks'] = self::modify_contact_form_blocks_recursive(
433+
$block['innerBlocks'],
434+
$new_attr
435+
);
436+
}
437+
}
438+
439+
return $blocks;
430440
}
431441

432442
/**

projects/packages/forms/tests/php/contact-form/Contact_Form_Test.php

Lines changed: 0 additions & 190 deletions
Original file line numberDiff line numberDiff line change
@@ -2248,196 +2248,6 @@ public function test_personal_data_eraser_pagination() {
22482248
$this->assertCount( 0, $posts, 'posts count matches after deleting the other feedback responder' );
22492249
}
22502250

2251-
/**
2252-
* Tests the functionality of the Util::grunion_contact_form_apply_block_attribute() function.
2253-
*/
2254-
public function test_grunion_contact_form_apply_block_attribute() {
2255-
// No contact form block.
2256-
$original = <<<'EOT'
2257-
<!-- wp:template-part {"slug":"post-meta-icons","theme":"pub/zoologist"} /-->
2258-
2259-
<!-- wp:spacer {"height":"150px"} -->
2260-
<div style="height:150px;" aria-hidden="true" class="wp-block-spacer"></div>
2261-
<!-- /wp:spacer -->
2262-
2263-
<!-- wp:group {"style":{"spacing":{"padding":{"top":"30px","right":"20px","bottom":"0px","left":"20px"}}},"layout":{"inherit":true}} -->
2264-
<div class="wp-block-group" style="padding-top:30px;padding-right:20px;padding-bottom:0;padding-left:20px;"><!-- wp:columns {"align":"wide","className":"next-prev-links"} -->
2265-
<div class="wp-block-columns alignwide next-prev-links"><!-- wp:column -->
2266-
<div class="wp-block-column"><!-- wp:post-navigation-link {"type":"previous","label":"←","showTitle":true} /--></div>
2267-
<!-- /wp:column -->
2268-
2269-
<!-- wp:column -->
2270-
<div class="wp-block-column"><!-- wp:post-navigation-link {"textAlign":"right","label":"→","showTitle":true} /--></div>
2271-
<!-- /wp:column --></div>
2272-
<!-- /wp:columns -->
2273-
2274-
<!-- wp:post-comments /--></div>
2275-
<!-- /wp:group -->
2276-
EOT;
2277-
$expected = <<<'EOT'
2278-
<!-- wp:template-part {"slug":"post-meta-icons","theme":"pub/zoologist"} /-->
2279-
2280-
<!-- wp:spacer {"height":"150px"} -->
2281-
<div style="height:150px;" aria-hidden="true" class="wp-block-spacer"></div>
2282-
<!-- /wp:spacer -->
2283-
2284-
<!-- wp:group {"style":{"spacing":{"padding":{"top":"30px","right":"20px","bottom":"0px","left":"20px"}}},"layout":{"inherit":true}} -->
2285-
<div class="wp-block-group" style="padding-top:30px;padding-right:20px;padding-bottom:0;padding-left:20px;"><!-- wp:columns {"align":"wide","className":"next-prev-links"} -->
2286-
<div class="wp-block-columns alignwide next-prev-links"><!-- wp:column -->
2287-
<div class="wp-block-column"><!-- wp:post-navigation-link {"type":"previous","label":"←","showTitle":true} /--></div>
2288-
<!-- /wp:column -->
2289-
2290-
<!-- wp:column -->
2291-
<div class="wp-block-column"><!-- wp:post-navigation-link {"textAlign":"right","label":"→","showTitle":true} /--></div>
2292-
<!-- /wp:column --></div>
2293-
<!-- /wp:columns -->
2294-
2295-
<!-- wp:post-comments /--></div>
2296-
<!-- /wp:group -->
2297-
EOT;
2298-
$this->assertEquals(
2299-
$expected,
2300-
Util::grunion_contact_form_apply_block_attribute( $original, array( 'foo' => 'bar' ) )
2301-
);
2302-
// Contact form block without attributes.
2303-
$original = <<<'EOT'
2304-
<!-- wp:template-part {"slug":"post-meta-icons","theme":"pub/zoologist"} /-->
2305-
2306-
<!-- wp:spacer {"height":"150px"} -->
2307-
<div style="height:150px;" aria-hidden="true" class="wp-block-spacer"></div>
2308-
<!-- /wp:spacer -->
2309-
2310-
<!-- wp:jetpack/contact-form -->
2311-
<div class="wp-block-jetpack-contact-form"><!-- wp:jetpack/field-name {"label":"Single Template","required":true} /-->
2312-
2313-
<!-- wp:jetpack/field-textarea /-->
2314-
2315-
<!-- wp:jetpack/button {"element":"button","text":"Contact Us"} /--></div>
2316-
<!-- /wp:jetpack/contact-form -->
2317-
2318-
<!-- wp:group {"style":{"spacing":{"padding":{"top":"30px","right":"20px","bottom":"0px","left":"20px"}}},"layout":{"inherit":true}} -->
2319-
<div class="wp-block-group" style="padding-top:30px;padding-right:20px;padding-bottom:0;padding-left:20px;"><!-- wp:columns {"align":"wide","className":"next-prev-links"} -->
2320-
<div class="wp-block-columns alignwide next-prev-links"><!-- wp:column -->
2321-
<div class="wp-block-column"><!-- wp:post-navigation-link {"type":"previous","label":"←","showTitle":true} /--></div>
2322-
<!-- /wp:column -->
2323-
2324-
<!-- wp:column -->
2325-
<div class="wp-block-column"><!-- wp:post-navigation-link {"textAlign":"right","label":"→","showTitle":true} /--></div>
2326-
<!-- /wp:column --></div>
2327-
<!-- /wp:columns -->
2328-
2329-
<!-- wp:post-comments /--></div>
2330-
<!-- /wp:group -->
2331-
EOT;
2332-
$expected = <<<'EOT'
2333-
<!-- wp:template-part {"slug":"post-meta-icons","theme":"pub/zoologist"} /-->
2334-
2335-
<!-- wp:spacer {"height":"150px"} -->
2336-
<div style="height:150px;" aria-hidden="true" class="wp-block-spacer"></div>
2337-
<!-- /wp:spacer -->
2338-
2339-
<!-- wp:jetpack/contact-form {"foo":"bar"} -->
2340-
<div class="wp-block-jetpack-contact-form"><!-- wp:jetpack/field-name {"label":"Single Template","required":true} /-->
2341-
2342-
<!-- wp:jetpack/field-textarea /-->
2343-
2344-
<!-- wp:jetpack/button {"element":"button","text":"Contact Us"} /--></div>
2345-
<!-- /wp:jetpack/contact-form -->
2346-
2347-
<!-- wp:group {"style":{"spacing":{"padding":{"top":"30px","right":"20px","bottom":"0px","left":"20px"}}},"layout":{"inherit":true}} -->
2348-
<div class="wp-block-group" style="padding-top:30px;padding-right:20px;padding-bottom:0;padding-left:20px;"><!-- wp:columns {"align":"wide","className":"next-prev-links"} -->
2349-
<div class="wp-block-columns alignwide next-prev-links"><!-- wp:column -->
2350-
<div class="wp-block-column"><!-- wp:post-navigation-link {"type":"previous","label":"←","showTitle":true} /--></div>
2351-
<!-- /wp:column -->
2352-
2353-
<!-- wp:column -->
2354-
<div class="wp-block-column"><!-- wp:post-navigation-link {"textAlign":"right","label":"→","showTitle":true} /--></div>
2355-
<!-- /wp:column --></div>
2356-
<!-- /wp:columns -->
2357-
2358-
<!-- wp:post-comments /--></div>
2359-
<!-- /wp:group -->
2360-
EOT;
2361-
$this->assertEquals(
2362-
$expected,
2363-
Util::grunion_contact_form_apply_block_attribute( $original, array( 'foo' => 'bar' ) )
2364-
);
2365-
// Contact form block with attributes.
2366-
$original = <<<'EOT'
2367-
<!-- wp:template-part {"slug":"post-meta-icons","theme":"pub/zoologist"} /-->
2368-
2369-
<!-- wp:spacer {"height":"150px"} -->
2370-
<div style="height:150px;" aria-hidden="true" class="wp-block-spacer"></div>
2371-
<!-- /wp:spacer -->
2372-
2373-
<!-- wp:jetpack/contact-form {"customThankyou":"message"} -->
2374-
<div class="wp-block-jetpack-contact-form"><!-- wp:jetpack/field-name {"label":"Single Template","required":true} /-->
2375-
2376-
<!-- wp:jetpack/field-textarea /-->
2377-
2378-
<!-- wp:jetpack/button {"element":"button","text":"Contact Us"} /--></div>
2379-
<!-- /wp:jetpack/contact-form -->
2380-
2381-
<!-- wp:group {"style":{"spacing":{"padding":{"top":"30px","right":"20px","bottom":"0px","left":"20px"}}},"layout":{"inherit":true}} -->
2382-
<div class="wp-block-group" style="padding-top:30px;padding-right:20px;padding-bottom:0;padding-left:20px;"><!-- wp:columns {"align":"wide","className":"next-prev-links"} -->
2383-
<div class="wp-block-columns alignwide next-prev-links"><!-- wp:column -->
2384-
<div class="wp-block-column"><!-- wp:post-navigation-link {"type":"previous","label":"←","showTitle":true} /--></div>
2385-
<!-- /wp:column -->
2386-
2387-
<!-- wp:column -->
2388-
<div class="wp-block-column"><!-- wp:post-navigation-link {"textAlign":"right","label":"→","showTitle":true} /--></div>
2389-
<!-- /wp:column --></div>
2390-
<!-- /wp:columns -->
2391-
2392-
<!-- wp:post-comments /--></div>
2393-
<!-- /wp:group -->
2394-
EOT;
2395-
$expected = <<<'EOT'
2396-
<!-- wp:template-part {"slug":"post-meta-icons","theme":"pub/zoologist"} /-->
2397-
2398-
<!-- wp:spacer {"height":"150px"} -->
2399-
<div style="height:150px;" aria-hidden="true" class="wp-block-spacer"></div>
2400-
<!-- /wp:spacer -->
2401-
2402-
<!-- wp:jetpack/contact-form {"customThankyou":"message","foo":"bar"} -->
2403-
<div class="wp-block-jetpack-contact-form"><!-- wp:jetpack/field-name {"label":"Single Template","required":true} /-->
2404-
2405-
<!-- wp:jetpack/field-textarea /-->
2406-
2407-
<!-- wp:jetpack/button {"element":"button","text":"Contact Us"} /--></div>
2408-
<!-- /wp:jetpack/contact-form -->
2409-
2410-
<!-- wp:group {"style":{"spacing":{"padding":{"top":"30px","right":"20px","bottom":"0px","left":"20px"}}},"layout":{"inherit":true}} -->
2411-
<div class="wp-block-group" style="padding-top:30px;padding-right:20px;padding-bottom:0;padding-left:20px;"><!-- wp:columns {"align":"wide","className":"next-prev-links"} -->
2412-
<div class="wp-block-columns alignwide next-prev-links"><!-- wp:column -->
2413-
<div class="wp-block-column"><!-- wp:post-navigation-link {"type":"previous","label":"←","showTitle":true} /--></div>
2414-
<!-- /wp:column -->
2415-
2416-
<!-- wp:column -->
2417-
<div class="wp-block-column"><!-- wp:post-navigation-link {"textAlign":"right","label":"→","showTitle":true} /--></div>
2418-
<!-- /wp:column --></div>
2419-
<!-- /wp:columns -->
2420-
2421-
<!-- wp:post-comments /--></div>
2422-
<!-- /wp:group -->
2423-
EOT;
2424-
$this->assertEquals(
2425-
$expected,
2426-
Util::grunion_contact_form_apply_block_attribute( $original, array( 'foo' => 'bar' ) )
2427-
);
2428-
2429-
// Check that the function return null if the function gets null.
2430-
$this->assertNull(
2431-
// @phan-suppress-next-line PhanTypeMismatchArgumentProbablyReal
2432-
Util::grunion_contact_form_apply_block_attribute( null, array( 'foo' => 'bar' ) )
2433-
);
2434-
2435-
// Check that the function returns an array if the function gets an empty array.
2436-
$this->assertEquals(
2437-
array(), // @phan-suppress-next-line PhanTypeMismatchArgumentProbablyReal
2438-
Util::grunion_contact_form_apply_block_attribute( array(), array( 'foo' => 'bar' ) )
2439-
);
2440-
}
24412251
/**
24422252
* Helper function that tracks the ids of the feedbacks that got created.
24432253
*/

0 commit comments

Comments
 (0)