Created
June 12, 2020 01:23
-
-
Save westonruter/340dfb31c09e7f82240161529e5ec93c to your computer and use it in GitHub Desktop.
Development plugin to test slow-loading images in content
This file contains hidden or 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 | |
/** | |
* Slow Content Images plugin bootstrap. | |
* | |
* @package Google\Mini_Plugin_Template | |
* @author Weston Ruter, Google | |
* @license GPL-2.0-or-later | |
* @copyright 2020 Google Inc. | |
* | |
* @wordpress-plugin | |
* Plugin Name: Slow Content Images | |
* Plugin URI: https://gist.github.com/westonruter/340dfb31c09e7f82240161529e5ec93c | |
* Description: Cause images in content to have an increasing delay before each starts loading. First image has a 3-second delay and each image after gets loaded 1 second after the next. | |
* Version: 0.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/340dfb31c09e7f82240161529e5ec93c | |
*/ | |
namespace Google\Slow_Content_Images; | |
use WP_Error; | |
use WP_REST_Request; | |
use WP_REST_Response; | |
const REST_NAMESPACE = 'slow-content-images/v1'; | |
add_filter( 'the_content', __NAMESPACE__ . '\filter_the_content', 1000 ); | |
add_action( 'rest_api_init', __NAMESPACE__ . '\register_proxy_route' ); | |
/** | |
* Register image proxy route. | |
*/ | |
function register_proxy_route() { | |
register_rest_route( | |
REST_NAMESPACE, | |
'/proxy/(?P<base64_url>.+)', | |
[ | |
'methods' => 'GET', | |
'callback' => __NAMESPACE__ . '\handle_rest_request', | |
'args' => [ | |
'sleep' => [ | |
'type' => 'int', | |
], | |
], | |
] | |
); | |
} | |
/** | |
* Handle image proxy request. | |
* | |
* @param WP_REST_Request $request Request. | |
* @return WP_Error|WP_REST_Response | |
*/ | |
function handle_rest_request( WP_REST_Request $request ) { | |
$slug = str_replace( | |
[ '-', '_' ], | |
[ '+', '/' ], | |
$request['base64_url'] | |
); | |
$url = base64_decode( $slug ); | |
if ( false === $url ) { | |
return new WP_Error( 'base64_error' ); | |
} | |
sleep( (int) $request['sleep'] ); | |
$response = new WP_REST_Response(); | |
$response->set_status( 302 ); | |
$response->header( 'Location', '//' . $url ); | |
return $response; | |
} | |
/** | |
* Filter the content to inject proxied image URLs. | |
* | |
* @param string $content Content. | |
* | |
* @return string Filtered content. | |
*/ | |
function filter_the_content( $content ) { | |
static $base_instances = []; | |
return preg_replace_callback( | |
// Look for image-looking URLs that may have query params following them. | |
'#(\bhttps?://)([^\s"\',]+?\.(?:jpe?g|png|gif|webp)(?:\?[^\s"\',]+)?)\b#', | |
function ( $matches ) use ( &$base_instances ) { | |
$url = html_entity_decode( $matches[2], ENT_QUOTES ); | |
$base = preg_replace( '/(-\d+x\d+)?\.\w+/', '', basename( wp_parse_url( $url, PHP_URL_PATH ) ) ); | |
if ( ! in_array( $base, $base_instances, true ) ) { | |
$base_instances[] = $base; | |
} | |
$sleep = 2 + ( array_search( $base, $base_instances, true ) * 2 ); | |
// Note that base64-encoding is to prevent some web servers from failing to image-looking URLs to WordPress. | |
$slug = str_replace( | |
[ '+', '/' ], | |
[ '-', '_' ], | |
base64_encode( $url ) | |
); | |
return esc_url( add_query_arg( | |
compact( 'sleep' ), | |
rest_url( '/' . REST_NAMESPACE . '/proxy/' . $slug ) | |
) ); | |
}, | |
$content | |
); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment