Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace img with amp-pixel when dealing with Facebook tracking pixel #6965

Merged
merged 9 commits into from
Mar 9, 2022
43 changes: 43 additions & 0 deletions includes/sanitizers/class-amp-img-sanitizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,26 @@ public function sanitize() {
continue;
}

// Replace img with amp-pixel when dealing with tracking pixels.
if ( self::is_tracking_pixel_url( $node->getAttribute( Attribute::SRC ) ) ) {
$attributes = [
Attribute::SRC => $node->getAttribute( Attribute::SRC ),
Attribute::LAYOUT => Layout::NODISPLAY,
];
foreach ( [ Attribute::REFERRERPOLICY ] as $allowed_attribute ) {
if ( $node->hasAttribute( $allowed_attribute ) ) {
$attributes[ $allowed_attribute ] = $node->getAttribute( $allowed_attribute );
}
}
$amp_pixel_node = AMP_DOM_Utils::create_node(
$this->dom,
Extension::PIXEL,
$attributes
);
$node->parentNode->replaceChild( $amp_pixel_node, $node );
continue;
}

// Short-circuit emoji images from needing to make requests out to https://s.w.org/.
if ( 'wp-smiley' === $node->getAttribute( Attribute::CLASS_ ) ) {
$node->setAttribute( Attribute::WIDTH, '72' );
Expand Down Expand Up @@ -552,4 +572,27 @@ private function is_gif_url( $url ) {
$path = wp_parse_url( $url, PHP_URL_PATH );
return substr( $path, -strlen( $ext ) ) === $ext;
}

/**
* Determines if a URL is a known tracking pixel URL.
*
* Currently, only Facebook tracking pixel URL is detected.
*
* @since 2.2.2
*
* @param string $url URL to inspect.
*
* @return bool Returns true if $url is a tracking pixel URL.
*/
private static function is_tracking_pixel_url( $url ) {
$parsed_url = wp_parse_url( $url );

return (
isset( $parsed_url['host'], $parsed_url['path'] )
&&
'facebook.com' === str_replace( 'www.', '', $parsed_url['host'] )
&&
'/tr' === $parsed_url['path']
);
}
}
54 changes: 54 additions & 0 deletions tests/php/test-amp-img-sanitizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,16 @@ public function get_data() {
AMP_Tag_And_Attribute_Sanitizer::WRONG_PARENT_TAG,
],
],

'facebook_pixel_img_to_amp_pixel' => [
'<img height="1" width="1" style="display:none" alt="fbpx" src="https://www.facebook.com/tr?id=123456789012345&ev=PageView&noscript=1" />',
'<amp-pixel src="https://www.facebook.com/tr?id=123456789012345&amp;ev=PageView&amp;noscript=1" layout="nodisplay"></amp-pixel>',
],

'facebook_pixel_img_to_amp_pixel_with_referrer' => [
'<img height="1" width="1" style="display:none" alt="fbpx" src="https://facebook.com/tr?id=123456789012345&ev=PageView&noscript=1" referrerpolicy="no-referrer">',
'<amp-pixel src="https://facebook.com/tr?id=123456789012345&amp;ev=PageView&amp;noscript=1" layout="nodisplay" referrerpolicy="no-referrer"></amp-pixel>',
],
];
}

Expand Down Expand Up @@ -923,4 +933,48 @@ public function test_process_picture_elements( $input, $args, $expected ) {

$this->assertEqualMarkup( $expected, $actual, "Actual content:\n$actual" );
}

/**
* @return array
*/
public function get_data_for_test_is_tracking_pixel_url() {
return [
'facebook_pixel_url_no_ssl_no_www' => [
'url' => 'http://facebook.com/tr?id=123456789012345',
'expected' => true,
],
'facebook_pixel_url_no_ssl_www' => [
'url' => 'http://www.facebook.com/tr?id=123456789012345',
'expected' => true,
],
'facebook_pixel_url_ssl_no_www' => [
'url' => 'https://facebook.com/tr?id=123456789012345',
'expected' => true,
],
'facebook_pixel_url_ssl_www' => [
'url' => 'https://www.facebook.com/tr?id=123456789012345',
'expected' => true,
],
'facebook_page_url' => [
'url' => 'https://www.facebook.com/traffic?id=123456789012345',
'expected' => false,
],
'relative_url' => [
'url' => '/tr?id=123456789012345',
'expected' => false,
],
];
}

/**
* @dataProvider get_data_for_test_is_tracking_pixel_url()
*
* @covers ::is_tracking_pixel_url()
*/
public function test_is_tracking_pixel_url( $url, $expected ) {
$this->assertEquals(
$expected,
$this->call_private_static_method( AMP_Img_Sanitizer::class, 'is_tracking_pixel_url', [ $url ] )
);
}
}