Last active
October 26, 2022 15:02
-
-
Save westonruter/8a171f6c561fd69ac33a032983dafaf3 to your computer and use it in GitHub Desktop.
Prototype to land as part of AMP Optimizer. See https://github.com/ampproject/amp-toolbox-php/issues/176
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* AMP Elevate Resource Hints plugin bootstrap. | |
* | |
* @package Google\AmpElevateResourceHints | |
* @author Weston Ruter, Google | |
* @license GPL-2.0-or-later | |
* @copyright 2021 Google Inc. | |
* | |
* @wordpress-plugin | |
* Plugin Name: AMP Elevate Resource Hints | |
* Plugin URI: https://gist.github.com/westonruter/8a171f6c561fd69ac33a032983dafaf3 | |
* Description: Prototype transformer which elevates <code>link</code> elements to <code>Link</code> response headers. This functionality will be incorporated into the Optimizer via <a href="https://github.com/ampproject/amp-toolbox-php/issues/176">amp-toolbox-php#176</a>. | |
* Version: 0.1.1 | |
* Author: Weston Ruter, Google | |
* Author URI: https://weston.ruter.net/ | |
* License: GNU General Public License v2 (or later) | |
* License URI: http://www.gnu.org/licenses/gpl-2.0.html | |
* Gist Plugin URI: https://gist.github.com/westonruter/8a171f6c561fd69ac33a032983dafaf3 | |
*/ | |
namespace Google\AmpElevateResourceHints; | |
use AmpProject\Optimizer; | |
/** | |
* Filter configuration array to register the transformer. | |
* | |
* @param array $configuration Associative array of configuration data. | |
* @return array Configuration. | |
*/ | |
function filter_amp_optimizer_config( array $configuration ) { | |
require_once __DIR__ . '/ElevateResourceHints.php'; | |
$configuration[ Optimizer\Configuration::KEY_TRANSFORMERS ][] = ElevateResourceHints::class; | |
return $configuration; | |
} | |
if ( empty( $_GET['amp_disable_elevate_resource_hints'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended | |
add_filter( 'amp_optimizer_config', __NAMESPACE__ . '\filter_amp_optimizer_config', PHP_INT_MAX ); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Elevate resource hints from link elements to headers. | |
* | |
* @link https://github.com/ampproject/amp-toolbox-php/issues/176 | |
* @package Google\AmpElevateResourceHints | |
*/ | |
namespace Google\AmpElevateResourceHints; | |
use AmpProject\Dom\Document; | |
use AmpProject\Optimizer\ErrorCollection; | |
use AmpProject\Optimizer\Transformer; | |
use AmpProject\Attribute; | |
use AmpProject\Dom\Element; | |
use DOMAttr; | |
/** | |
* This is a hack to send headers as part of a transformer! This is only needed because the transformer doesn't currently | |
* take a collection for mutating the HTTP headers. See <https://github.com/ampproject/amp-toolbox-php/issues/176#issuecomment-812142640>. | |
*/ | |
final class ElevateResourceHints implements Transformer { | |
/** | |
* Attributes from link elements (other than href) to surface to Link header. | |
* | |
* @var string[] | |
*/ | |
const ELEVATED_LINK_ATTRIBUTES = [ | |
Attribute::AS_, | |
Attribute::CROSSORIGIN, | |
Attribute::IMAGESIZES, | |
Attribute::IMAGESRCSET, | |
Attribute::REFERRERPOLICY, | |
Attribute::REL, | |
'integrity', | |
'prefetch', | |
]; | |
/** | |
* Link relations that should get elevated to Link headers. | |
* | |
* @var string[] | |
*/ | |
const ELEVATED_LINK_RELATIONS = [ | |
Attribute::REL_DNS_PREFETCH, | |
Attribute::REL_PRECONNECT, | |
Attribute::REL_PRELOAD, | |
Attribute::REL_MODULEPRELOAD, | |
]; | |
/** | |
* Apply transformations to the provided DOM document. | |
* | |
* @param Document $document DOM document to apply the transformations to. | |
* @param ErrorCollection $errors Collection of errors that are collected during transformation. | |
*/ | |
public function transform( Document $document, ErrorCollection $errors ) { | |
$links = $document->xpath->query( './link[ @rel and @href ]', $document->head ); | |
foreach ( $links as $link ) { | |
/** @var Element $link */ | |
$relations = preg_split( '/\s+/', trim( $link->getAttribute( Attribute::REL ) ) ); | |
if ( 0 === count( array_intersect( $relations, self::ELEVATED_LINK_RELATIONS ) ) ) { | |
continue; | |
} | |
$header = sprintf( 'Link: <%s>', esc_url_raw( $link->getAttribute( Attribute::HREF ) ) ); | |
foreach ( $link->attributes as $attribute ) { | |
/** @var DOMAttr $attribute */ | |
if ( in_array( $attribute->nodeName, self::ELEVATED_LINK_ATTRIBUTES, true ) ) { | |
$header .= sprintf( '; %s="%s"', $attribute->nodeName, addcslashes( $attribute->nodeValue, '"\\' ) ); | |
} | |
} | |
header( $header, false ); | |
$link->parentNode->removeChild( $link ); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Installation instructions: https://gist.github.com/westonruter/6110fbc4bef0c4b8c021a112012f7e9c