fix: includes
This commit is contained in:
22
.editorconfig
Normal file
22
.editorconfig
Normal file
@@ -0,0 +1,22 @@
|
||||
# This file is for unifying the coding style for different editors and IDEs
|
||||
# editorconfig.org
|
||||
|
||||
# WordPress Coding Standards
|
||||
# https://make.wordpress.org/core/handbook/coding-standards/
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
|
||||
[{.jshintrc,*.json,*.yml}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[{*.txt,wp-config-sample.php}]
|
||||
end_of_line = crlf
|
||||
11
.gitignore
vendored
Normal file
11
.gitignore
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
.DS_Store
|
||||
phpunit.xml
|
||||
Thumbs.db
|
||||
wp-cli.local.yml
|
||||
node_modules/
|
||||
*.sql
|
||||
*.tar.gz
|
||||
*.zip
|
||||
/vendor
|
||||
.idea
|
||||
composer.lock
|
||||
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 eighteen73
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
62
README.md
Normal file
62
README.md
Normal file
@@ -0,0 +1,62 @@
|
||||
# Thumbor for WordPress
|
||||
|
||||
**This plugin is in early development and may yet undergo changes that affect its functionality. Use it at your own risk until we publish a versioned release.**
|
||||
|
||||
This plugin modifies Wordpress image URLs so they can be served from [Thumbor](https://www.thumbor.org/).
|
||||
|
||||
A well configured Thumbor server can deliver highly optimised images to improve website load times, and take a large of your web server by removing the need for WordPress to generate image derivatives for itself.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
You need access to a Thumbor service to use this plugin.
|
||||
|
||||
Note this typically only works on remote WordPress websites because Thumbor needs web access to the uploaded images. With some environment configuration you may be able to make it work in a development environment but that setup is outside the scope of this plugin.
|
||||
|
||||
## Installation
|
||||
|
||||
Install and activate the plugin as normal then add the following configuration to your website.
|
||||
|
||||
```php
|
||||
define( 'THUMBOR_URL', 'https://media.example.com' );
|
||||
define( 'THUMBOR_SECRET_KEY', 'your_thumbor_secret_key' );
|
||||
```
|
||||
|
||||
If you Thumbor server runs in unsafe mode (which is _highly_ discouraged) you may set `THUMBOR_SECRET_KEY` to `null`.
|
||||
|
||||
### Optional: Disabling “big image” resizing
|
||||
|
||||
WordPress can automatically resize large image uploads which will save unnecessarily large requests from your Thumbor server. This plugin can change that limit with the following configuration.
|
||||
|
||||
```php
|
||||
# Disable “big image” resizing
|
||||
define( 'THUMBOR_UPLOAD_IMAGE_THRESHOLD', false );
|
||||
|
||||
# Set the longest image edge
|
||||
define( 'THUMBOR_UPLOAD_IMAGE_THRESHOLD', 2000 );
|
||||
```
|
||||
|
||||
See [`big_image_size_threshold`](https://developer.wordpress.org/reference/hooks/big_image_size_threshold/) docs for more information.
|
||||
|
||||
### Optional: Delete prior image files
|
||||
|
||||
Once the plugin is enabled you can make use of a WP-CLI command to delete any image derivatives that have already been created.
|
||||
|
||||
**Use this command with great care because it will delete media files from your server.**
|
||||
|
||||
```shell
|
||||
wp media regenerate
|
||||
```
|
||||
|
||||
## Deactivating/pausing the plugin
|
||||
|
||||
The plugin automatically deactivates itself when `THUMBOR_URL` is not set. So in your development environment you can remove the above configuration to make WordPress return to its default behaviour.
|
||||
|
||||
While enabled the plugin has prevented WordPress from making it's own resized versions of images. You can use the following WP-CLI command to generate any missing images after disabling the plugin:
|
||||
|
||||
```shell
|
||||
wp media regenerate --only-missing
|
||||
```
|
||||
|
||||
## Credits
|
||||
|
||||
This plugin is heavily based on code that was forked from the [Tachyon plugin](https://github.com/humanmade/tachyon-plugin) by Human Made. All due credit to the authors of that plugin.
|
||||
23
composer.json
Normal file
23
composer.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"name": "eighteen73/wordpress-thumbor",
|
||||
"description": "A WordPress plugin to serve media via a Thumbor server",
|
||||
"type": "wordpress-plugin",
|
||||
"license": "MIT",
|
||||
"minimum-stability": "stable",
|
||||
"require": {
|
||||
"php": ">=8.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Eighteen73\\Thumbor\\": "includes/classes/"
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"allow-plugins": {
|
||||
"dealerdirect/phpcodesniffer-composer-installer": true
|
||||
}
|
||||
},
|
||||
"require-dev": {
|
||||
"eighteen73/wordpress-coding-standards": "^2.0.0"
|
||||
}
|
||||
}
|
||||
99
includes/classes/Thumbor/MediaOverrides.php
Normal file
99
includes/classes/Thumbor/MediaOverrides.php
Normal file
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
/**
|
||||
* Override native media behaviour.
|
||||
*
|
||||
* @package wordpress-thumbor
|
||||
*/
|
||||
|
||||
namespace Eighteen73\Thumbor;
|
||||
|
||||
/**
|
||||
* Plugin singleton class.
|
||||
*/
|
||||
class MediaOverrides {
|
||||
/**
|
||||
* Oh look, a singleton!
|
||||
*
|
||||
* @var Thumbor|null
|
||||
*/
|
||||
private static $instance = null;
|
||||
|
||||
/**
|
||||
* Singleton implementation
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public static function instance() {
|
||||
|
||||
if ( ! defined( 'THUMBOR_URL' ) || empty( THUMBOR_URL ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! is_a( self::$instance, __CLASS__ ) ) {
|
||||
$class = get_called_class();
|
||||
self::$instance = new $class();
|
||||
self::$instance->setup();
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Silence is golden.
|
||||
*/
|
||||
private function __construct() {}
|
||||
|
||||
/**
|
||||
* Register actions and filters, but only if basic Thumbor functions are available.
|
||||
* The basic functions are found in ./wordpress-thumbor.php.
|
||||
*
|
||||
* @uses add_action, add_filter
|
||||
* @return null
|
||||
*/
|
||||
private function setup() {
|
||||
|
||||
if ( ! function_exists( 'thumbor_url' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't scale down big images
|
||||
add_filter( 'big_image_size_threshold', [ $this, 'image_threshold' ], 999, 1 );
|
||||
|
||||
// Don't resize any images
|
||||
add_filter( 'intermediate_image_sizes_advanced', [ $this, 'prevent_resizing' ], 10, 5 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevents any images from being automatically created.
|
||||
*
|
||||
* @param int $threshold The threshold value in pixels.
|
||||
*
|
||||
* @return bool|int The new “big image” threshold value.
|
||||
*/
|
||||
public static function image_threshold( $threshold ) {
|
||||
|
||||
if ( ! defined( 'THUMBOR_UPLOAD_IMAGE_THRESHOLD' ) ) {
|
||||
return $threshold;
|
||||
}
|
||||
|
||||
if ( THUMBOR_UPLOAD_IMAGE_THRESHOLD === false ) {
|
||||
return false;
|
||||
} elseif ( is_int( THUMBOR_UPLOAD_IMAGE_THRESHOLD ) ) {
|
||||
return THUMBOR_UPLOAD_IMAGE_THRESHOLD;
|
||||
}
|
||||
|
||||
return $threshold;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevents any images from being automatically created.
|
||||
*
|
||||
* @param array $sizes Associative array of image sizes to be created.
|
||||
* @param array $image_meta The image meta data: width, height, file, sizes, etc.
|
||||
*
|
||||
* @return array Associative array of image sizes to be created.
|
||||
*/
|
||||
public static function prevent_resizing( $sizes, $image_meta ) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
1031
includes/classes/Thumbor/ThumborImage.php
Normal file
1031
includes/classes/Thumbor/ThumborImage.php
Normal file
File diff suppressed because it is too large
Load Diff
23
phpcs.xml
Normal file
23
phpcs.xml
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0"?>
|
||||
<ruleset name="WordPress-Thumbor">
|
||||
<description>WordPress Thumbor</description>
|
||||
|
||||
<!-- Scan all files in directory -->
|
||||
<file>.</file>
|
||||
<exclude-pattern type="relative">lib/packages/*</exclude-pattern>
|
||||
|
||||
<!-- Scan only PHP files -->
|
||||
<arg name="extensions" value="php"/>
|
||||
|
||||
<!-- Show colors in console -->
|
||||
<arg value="-colors"/>
|
||||
|
||||
<!-- Show sniff codes in all reports -->
|
||||
<arg value="ns"/>
|
||||
|
||||
<rule ref="Squiz.PHP.EmbeddedPhp">
|
||||
<exclude name="Squiz.Commenting.FileComment.Missing"/>
|
||||
</rule>
|
||||
|
||||
<rule ref="Eighteen73-WordPress-Default" />
|
||||
</ruleset>
|
||||
138
wordpress-thumbor.php
Normal file
138
wordpress-thumbor.php
Normal file
@@ -0,0 +1,138 @@
|
||||
<?php
|
||||
/**
|
||||
* Plugin Name: WordPress Thumbor
|
||||
* Plugin URI: https://github.com/eighteen73/wordpress-thumbor
|
||||
* Description: A WordPress plugin to serve media via a Thumbor server
|
||||
* Author: eighteen73 Web Team
|
||||
* Author URI: https://eighteen73.co.uk
|
||||
* Update URI: https://github.com/eighteen73/wordpress-thumbor
|
||||
* Text Domain: wordpress-thumbor
|
||||
*
|
||||
* @package wordpress-thumbor
|
||||
*/
|
||||
|
||||
use Eighteen73\Thumbor\MediaOverrides;
|
||||
use Eighteen73\Thumbor\ThumborImage;
|
||||
|
||||
spl_autoload_register(
|
||||
function ( $class_name ) {
|
||||
$path_parts = explode( '\\', $class_name );
|
||||
|
||||
if ( ! empty( $path_parts ) ) {
|
||||
$package = $path_parts[0];
|
||||
|
||||
unset( $path_parts[0] );
|
||||
|
||||
if ( 'Eighteen73' === $package ) {
|
||||
require_once __DIR__ . '/includes/classes/' . implode( '/', $path_parts ) . '.php';
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
MediaOverrides::instance();
|
||||
ThumborImage::instance();
|
||||
|
||||
/**
|
||||
* Generates a Thumbor URL.
|
||||
*
|
||||
* @see https://docs.altis-dxp.com/media/dynamic-images/
|
||||
*
|
||||
* @param string $image_url URL to the publicly accessible image you want to manipulate.
|
||||
* @param array|string $args An array of arguments, i.e. array( 'w' => '300', 'resize' => array( 123, 456 ) ), or in string form (w=123&h=456).
|
||||
* @param string|null $scheme One of http or https.
|
||||
* @return string The raw final URL. You should run this through esc_url() before displaying it.
|
||||
*/
|
||||
function thumbor_url( $image_url, $args = [], $scheme = null ) {
|
||||
|
||||
if ( ! defined( 'THUMBOR_URL' ) || empty( THUMBOR_URL ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Cache result for unique set of args to save reruns. This is because we're seeing the same image being re-run within a single
|
||||
* request and there's a chance that filters applied within are expensive. A short TTL is used in case persistent cache is used
|
||||
* but it doesn't need to be longed lived.
|
||||
*/
|
||||
$cache_key = md5( $image_url . json_encode( $args ) . ( $scheme ?? '' ) );
|
||||
$cache_ttl = 60;
|
||||
$cached_url = wp_cache_get( $cache_key, 'thumbor_url' );
|
||||
if ( $cached_url ) {
|
||||
return $cached_url;
|
||||
}
|
||||
|
||||
$upload_dir = wp_upload_dir();
|
||||
$upload_baseurl = $upload_dir['baseurl'];
|
||||
|
||||
if ( is_multisite() ) {
|
||||
$upload_baseurl = preg_replace( '#/sites/[\d]+#', '', $upload_baseurl );
|
||||
}
|
||||
|
||||
$image_url = trim( $image_url );
|
||||
|
||||
$image_file = basename( parse_url( $image_url, PHP_URL_PATH ) );
|
||||
$image_url = str_replace( $image_file, urlencode( $image_file ), $image_url );
|
||||
|
||||
if ( strpos( $image_url, $upload_baseurl ) !== 0 ) {
|
||||
return $image_url;
|
||||
}
|
||||
|
||||
if ( false !== apply_filters( 'thumbor_skip_for_url', false, $image_url, $args, $scheme ) ) {
|
||||
return $image_url;
|
||||
}
|
||||
|
||||
$image_url = apply_filters( 'thumbor_pre_image_url', $image_url, $args, $scheme );
|
||||
$args = apply_filters( 'thumbor_pre_args', $args, $image_url, $scheme );
|
||||
|
||||
if ( isset( $args['fit'] ) ) {
|
||||
$scale = 'fit-in';
|
||||
$width = $args['fit'][0];
|
||||
$height = $args['fit'][1];
|
||||
} elseif ( isset( $args['resize'] ) ) {
|
||||
$scale = null;
|
||||
$width = $args['resize'][0];
|
||||
$height = $args['resize'][1];
|
||||
} elseif ( isset( $args['w'] ) ) {
|
||||
$scale = 'fit-in';
|
||||
$width = $args['w'];
|
||||
$height = 'orig';
|
||||
} elseif ( isset( $args['h'] ) ) {
|
||||
$scale = 'fit-in';
|
||||
$width = 'orig';
|
||||
$height = $args['h'];
|
||||
} else {
|
||||
$scale = 'fit-in';
|
||||
$width = 'orig';
|
||||
$height = 'orig';
|
||||
}
|
||||
|
||||
$url_parts = [
|
||||
'scale' => $scale,
|
||||
'size' => "{$width}x{$height}",
|
||||
'filters' => null,
|
||||
'smart' => null,
|
||||
];
|
||||
|
||||
$thumbor_url = implode( '/', array_filter( $url_parts ) ) . '/' . urlencode( $image_url );
|
||||
|
||||
if ( defined( 'THUMBOR_SECRET_KEY' ) && ! empty( THUMBOR_SECRET_KEY ) ) {
|
||||
$signature = hash_hmac( 'sha1', $thumbor_url, THUMBOR_SECRET_KEY, true );
|
||||
$thumbor_url = rtrim( THUMBOR_URL, '/' ) . '/' . strtr( base64_encode( $signature ), '/+', '_-' ) . '/' . $thumbor_url;
|
||||
} else {
|
||||
$thumbor_url = rtrim( THUMBOR_URL, '/' ) . '/unsafe/' . $thumbor_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows a final modification of the generated Thumbor URL.
|
||||
*
|
||||
* @param string $thumbor_url The final Thumbor image URL including query args.
|
||||
* @param string $image_url The image URL without query args.
|
||||
* @param array $args A key value array of the query args appended to $image_url.
|
||||
*/
|
||||
$final_thumbor_url = apply_filters( 'thumbor_url', $thumbor_url, $image_url, $args );
|
||||
|
||||
// Cache result to save reruns
|
||||
wp_cache_set( $cache_key, $final_thumbor_url, 'thumbor_url', $cache_ttl );
|
||||
|
||||
return $final_thumbor_url;
|
||||
}
|
||||
Reference in New Issue
Block a user