Skip to content

Commit dcf64cd

Browse files
authoredJul 12, 2024··
Fix Remove CSS/JS URL matching (#911)
* Fix matching * Fix regex * Match both directions * Add Util_Environment::array_intersect_partial() unit test
1 parent 522f804 commit dcf64cd

4 files changed

+163
-14
lines changed
 

‎UserExperience_Remove_CssJs_Mutator.php

+9-13
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ public function run( $buffer ) {
104104
}
105105

106106
$this->buffer = preg_replace_callback(
107-
'~(<link.+?href.+?>)|(<script.+?src.+?</script>)~is',
107+
'~(<link[^>]+href[^>]+>)|(<script[^>]+src[^>]+></script>)~is',
108108
array( $this, 'remove_content' ),
109109
$this->buffer
110110
);
@@ -154,26 +154,22 @@ private function is_content_included( $content ) {
154154
}
155155
}
156156

157-
// Build array of possible current page relative/absolute URLs.
157+
// Build array of possible current page URLs.
158158
$current_pages = array(
159-
$wp->request,
160-
trailingslashit( $wp->request ),
161-
home_url( $wp->request ),
162-
trailingslashit( home_url( $wp->request ) ),
159+
esc_url( trailingslashit( home_url( $wp->request ) ) ),
163160
);
164161

162+
if ( ! empty( $_SERVER['REQUEST_URI'] ) ) {
163+
$current_pages[] = esc_url( trailingslashit( home_url( sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ) ) ) );
164+
}
165+
165166
foreach ( $this->singles_includes as $id => $data ) {
166167
// Check if the defined single CSS/JS file is present in HTML content.
167168
if ( ! empty( $data ) && strpos( $content, $data['url_pattern'] ) !== false ) {
168169
// Check if current page URL(s) match any defined conditions.
169-
$page_match = array_intersect(
170+
$page_match = Util_Environment::array_intersect_partial(
170171
$current_pages,
171-
array_map(
172-
function ($value) {
173-
return ltrim( $value, '/' );
174-
},
175-
$data['includes']
176-
)
172+
$data['includes']
177173
);
178174

179175
// Check if current page content match any defined conditions.

‎UserExperience_Remove_CssJs_Page_View.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@
200200
'w3-total-cache'
201201
),
202202
'<strong>',
203-
'</strong>',
203+
'</strong>'
204204
),
205205
array(
206206
'strong' => array(),

‎Util_Environment.php

+52
Original file line numberDiff line numberDiff line change
@@ -1612,4 +1612,56 @@ public static function textarea_to_array( $value ) {
16121612

16131613
return $values_array;
16141614
}
1615+
1616+
/**
1617+
* Is there a partial array intersections match?
1618+
*
1619+
* Returns true if any entries between the tewo arrays match string endings or in whole.
1620+
*
1621+
* @since X.X.X
1622+
* @static
1623+
*
1624+
* @param array $array1 Array 1.
1625+
* @param array $array2 Array 2.
1626+
* @return bool
1627+
*/
1628+
public static function array_intersect_partial( array $array1, array $array2 ): bool {
1629+
foreach ( $array1 as $url1 ) {
1630+
foreach ( $array2 as $url2 ) {
1631+
/**
1632+
* Parse array1 URLs to handle both full URLs and relative paths.
1633+
* If homepage then 'path' will be null, set to '/'.
1634+
*/
1635+
$parsed_url1 = \wp_parse_url( \trim( $url1, '/' ) );
1636+
$parsed_url1['path'] = $parsed_url1['path'] ?? '/';
1637+
1638+
/**
1639+
* Parse array2 URLs to handle both full URLs and relative paths.
1640+
* If value is '/' for homepage then don't trim, otherwise tirm.
1641+
*/
1642+
$parsed_url2 = \wp_parse_url( '/' === $url2 ? '/' : \trim( $url2, '/' ) );
1643+
1644+
$is_host_set = isset( $parsed_url1['host'], $parsed_url2['host'] );
1645+
1646+
if ( $url1 === $url2 ) {
1647+
// Direct comparison for full URLs that are identical.
1648+
return true;
1649+
} elseif (
1650+
isset( $parsed_url1['path'], $parsed_url2['path'] )
1651+
&& (
1652+
\substr( $parsed_url1['path'], -\strlen( $parsed_url2['path'] ) ) === $parsed_url2['path'] ||
1653+
\substr( $parsed_url2['path'], -\strlen( $parsed_url1['path'] ) ) === $parsed_url1['path']
1654+
) && ( ! $is_host_set || ( $is_host_set && $parsed_url1['host'] === $parsed_url2['host'] ) )
1655+
) {
1656+
/**
1657+
* Check if both parsed URLs have 'path' and 'host' component and if they match.
1658+
* If either 'host' is not set but 'path' matches, consider it a match.
1659+
*/
1660+
return true;
1661+
}
1662+
}
1663+
}
1664+
1665+
return false;
1666+
}
16151667
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
<?php
2+
/**
3+
* File: class-w3tc-admin-util-environment.php
4+
*
5+
* @package W3TC
6+
* @subpackage W3TC/tests/admin
7+
* @author BoldGrid <development@boldgrid.com>
8+
* @since X.X.X
9+
* @link https://www.boldgrid.com/w3-total-cache/
10+
*/
11+
12+
declare( strict_types = 1 );
13+
14+
use W3TC\Util_Environment;
15+
16+
/**
17+
* Class: W3tc_Admin_Util_File_Test
18+
*
19+
* @since X.X.X
20+
*/
21+
class W3tc_Admin_Util_Environment extends WP_UnitTestCase {
22+
/**
23+
* Test array_intersect_partial().
24+
*
25+
* @since X.X.X
26+
*/
27+
public function test_array_intersect_partial() {
28+
// Ensure matches.
29+
$data = array(
30+
array(
31+
array( 'https://www.example.com/test.php' ),
32+
array( '/test.php' ),
33+
),
34+
array(
35+
array( '/test.php' ),
36+
array( 'https://www.example.com/test.php' ),
37+
),
38+
array(
39+
array( 'https://www.example.com/test.php' ),
40+
array( 'test.php' ),
41+
),
42+
array(
43+
array( 'test.php' ),
44+
array( 'https://www.example.com/test.php' ),
45+
),
46+
array(
47+
array( 'https://www.example.com/match' ),
48+
array(
49+
'/test.php',
50+
'/extra.php',
51+
'nomatch',
52+
'match',
53+
),
54+
),
55+
);
56+
57+
foreach ( $data as $set ) {
58+
$this->assertTrue( Util_Environment::array_intersect_partial( $set[0], $set[1] ) );
59+
}
60+
61+
// Ensure no matches.
62+
$data = array(
63+
array(
64+
array( 'https://www.example.com/test.php' ),
65+
array( '/' ),
66+
),
67+
array(
68+
array( '/' ),
69+
array( 'https://www.example.com/test.php' ),
70+
),
71+
array(
72+
array( 'https://www.example.com/test.php' ),
73+
array( 'nomatch.php' ),
74+
),
75+
array(
76+
array( 'nomatch.php' ),
77+
array( 'https://www.example.com/test.php' ),
78+
),
79+
array(
80+
array( 'https://www.example.com/test.php' ),
81+
array( '/test2.php' ),
82+
),
83+
array(
84+
array( 'https://www.example.com/test.php' ),
85+
array( 'https://www.example.com/test2.php' ),
86+
),
87+
array(
88+
array( 'https://www.example.com/match' ),
89+
array(
90+
'/test.php',
91+
'/extra.php',
92+
'nomatch',
93+
),
94+
),
95+
);
96+
97+
foreach ( $data as $set ) {
98+
$this->assertFalse( Util_Environment::array_intersect_partial( $set[0], $set[1] ) );
99+
}
100+
}
101+
}

0 commit comments

Comments
 (0)
Please sign in to comment.