-
Notifications
You must be signed in to change notification settings - Fork 39
Select converted images via .htaccess #94
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
Open
tijmenbruggeman
wants to merge
39
commits into
tinify:master
Choose a base branch
from
wcreateweb:task/conversion-server-side
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
39 commits
Select commit
Hold shift + click to select a range
46d9f9b
chore: add server support checks
tijmenbruggeman 37fe8a4
Merge branch 'master' of github.com:wcreateweb/wordpress-plugin into …
tijmenbruggeman d60d05f
chore: import server capabilities in root plugin file
tijmenbruggeman f8dc8e9
chore: refactor conversion settings into seperate views
tijmenbruggeman ce741e2
fix: echo enabled check
tijmenbruggeman 31c82e2
fix: use correct value from convert_format options
tijmenbruggeman f6eaf25
chore: format phpcs
tijmenbruggeman 2413f11
chore: add apache rewriter for webp and avif
tijmenbruggeman 9719011
Merge branch 'master' of github.com:wcreateweb/wordpress-plugin into …
tijmenbruggeman 34905ce
refactor: simplify Apache rewrite rules and rename methods
tijmenbruggeman 3752cef
test: add delivery method option to conversion settings utility
tijmenbruggeman 4061361
test: add data-testid attribute to radio button inputs
tijmenbruggeman c1b86eb
feat: add server-side image conversion via Apache rewrite rules
tijmenbruggeman 4680f5c
release: 3.6.10
Sreini b11dadb
Merge branch 'master' of github.com:wcreateweb/wordpress-plugin into …
tijmenbruggeman e195502
Format
tijmenbruggeman 864f3a3
chore: readd radio button
tijmenbruggeman c83f338
add conversio class to initialize picture or apache
tijmenbruggeman e154eb9
Merge branch 'master' of https://github.com/tinify/wordpress-plugin
tijmenbruggeman f53f00b
Merge branch 'tinify:master' into master
tijmenbruggeman 840db6d
Merge branch 'master' of github.com:wcreateweb/wordpress-plugin into …
tijmenbruggeman 76f4232
test and docs
tijmenbruggeman 913b4f3
Uninstal rules on uninstall
tijmenbruggeman 37129e2
format
tijmenbruggeman 8f9c839
format
tijmenbruggeman d64f6e9
add tests
tijmenbruggeman f81e1bf
Remove cache and only vary accept when it is an image
tijmenbruggeman 9e3b4ec
only write into uploads dir
tijmenbruggeman e053543
typo
tijmenbruggeman cbaf596
add query parameter for original bypass
tijmenbruggeman a49dd8f
Move hook to init
tijmenbruggeman 9d433f4
Format
tijmenbruggeman 4c03162
fix style
tijmenbruggeman bac9e7b
Lint
tijmenbruggeman 1cf893d
format
tijmenbruggeman f2a0a91
Only apply convertion settings when conversion is enabled
tijmenbruggeman 795b939
check delivery method incorrect
tijmenbruggeman a25c9a6
Resolve integration tests
tijmenbruggeman e94a2d3
chore: revert logger changes from conversion branch
tijmenbruggeman File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,166 @@ | ||
| <?php | ||
| /* | ||
| * Tiny Compress Images - WordPress plugin. | ||
| * Copyright (C) 2015-2018 Tinify B.V. | ||
| * | ||
| * This program is free software; you can redistribute it and/or modify it | ||
| * under the terms of the GNU General Public License as published by the Free | ||
| * Software Foundation; either version 2 of the License, or (at your option) | ||
| * any later version. | ||
| * | ||
| * This program is distributed in the hope that it will be useful, but WITHOUT | ||
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| * more details. | ||
| * | ||
| * You should have received a copy of the GNU General Public License along | ||
| * with this program; if not, write to the Free Software Foundation, Inc., 51 | ||
| * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n*/ | ||
|
|
||
| /** | ||
| * Tiny_Apache_Rewrite | ||
| * class responsible for the apache rules for image delivery. | ||
| * - toggling the rules when saving settings | ||
| * - inserting/removing rules from htaccess | ||
| * | ||
| * We are only updating rules when: | ||
| * - updating the option convert_format | ||
| * - uninstalling the plug-in | ||
| */ | ||
| class Tiny_Apache_Rewrite extends Tiny_WP_Base { | ||
|
|
||
| /** | ||
| * seperator when rules are inserted | ||
| * @var string | ||
| */ | ||
| const MARKER = 'tiny-compress-images'; | ||
|
|
||
| /** | ||
| * Installs or uninstalls the htaccess rules | ||
| * hooked into `update_option_tinypng_convert_format` | ||
| * https://developer.wordpress.org/reference/hooks/update_option_option/ | ||
| * | ||
| * | ||
| * @param mixed $old_value | ||
| * @param mixed $value | ||
| * @param string $option | ||
| * @return void | ||
| */ | ||
| public static function toggle_rules( $old_value, $value, $option ) { | ||
| $old_delivery = isset( $old_value['delivery_method'] ) ? | ||
| $old_value['delivery_method'] : null; | ||
| $new_delivery = isset( $value['delivery_method'] ) ? | ||
| $value['delivery_method'] : null; | ||
|
|
||
| if ( $old_delivery === $new_delivery ) { | ||
| return; | ||
| } | ||
|
|
||
| if ( 'htaccess' === $new_delivery ) { | ||
| self::install_rules(); | ||
| Tiny_Logger::debug( 'Installed image delivery rules' ); | ||
| return; | ||
| } | ||
|
|
||
| // We only uninstall if we were previously using htaccess | ||
| if ( 'htaccess' === $old_delivery ) { | ||
| self::uninstall_rules(); | ||
| Tiny_Logger::debug( 'Uninstalled image delivery rules' ); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Generate .htaccess rewrite rules for serving WebP and AVIF images. | ||
| * | ||
| * @return string The .htaccess rules | ||
| */ | ||
| private static function get_rewrite_rules() { | ||
| $rules = array(); | ||
| $rules[] = '<IfModule mod_rewrite.c>'; | ||
| $rules[] = 'RewriteEngine On'; | ||
| $rules[] = 'RewriteOptions Inherit'; | ||
|
|
||
| $rules = array_merge( $rules, self::get_avif_rules() ); | ||
| $rules = array_merge( $rules, self::get_webp_rules() ); | ||
|
|
||
| $rules[] = '</IfModule>'; | ||
|
|
||
| $rules[] = '<IfModule mod_headers.c>'; | ||
| $rules[] = '<FilesMatch "\.(jpe?g|png|gif)$">'; | ||
| $rules[] = 'Header append Vary Accept'; | ||
| $rules[] = '</FilesMatch>'; | ||
| $rules[] = '</IfModule>'; | ||
|
|
||
| $rules[] = '<IfModule mod_mime.c>'; | ||
| $rules[] = 'AddType image/webp .webp'; | ||
| $rules[] = 'AddType image/avif .avif'; | ||
| $rules[] = '</IfModule>'; | ||
|
|
||
| return implode( "\n", $rules ); | ||
| } | ||
|
|
||
| /** | ||
| * Generate AVIF rewrite rules. | ||
| * | ||
| * @return array[] AVIF rewrite rules | ||
| */ | ||
| private static function get_avif_rules() { | ||
| $rules = array(); | ||
| $rules[] = 'RewriteCond %{HTTP_ACCEPT} image/avif'; | ||
| $rules[] = 'RewriteCond %{REQUEST_URI} ^(.+)\.(?:jpe?g|png|gif)$'; | ||
| $rules[] = 'RewriteCond %{DOCUMENT_ROOT}/%1.avif -f'; | ||
| $rules[] = 'RewriteCond %{QUERY_STRING} !type=original'; | ||
| $rules[] = 'RewriteRule (.+)\.(?:jpe?g|png|gif)$ $1.avif [T=image/avif,L]'; | ||
| return $rules; | ||
| } | ||
|
|
||
| /** | ||
| * Generate WebP rewrite rules. | ||
| * | ||
| * @return array[] WebP rewrite rules | ||
| */ | ||
| private static function get_webp_rules() { | ||
| $rules = array(); | ||
| $rules[] = 'RewriteCond %{HTTP_ACCEPT} image/webp'; | ||
| $rules[] = 'RewriteCond %{REQUEST_URI} ^(.+)\.(?:jpe?g|png|gif)$'; | ||
| $rules[] = 'RewriteCond %{DOCUMENT_ROOT}/%1.webp -f'; | ||
| $rules[] = 'RewriteCond %{QUERY_STRING} !type=original'; | ||
| $rules[] = 'RewriteRule (.+)\.(?:jpe?g|png|gif)$ $1.webp [T=image/webp,L]'; | ||
|
|
||
| return $rules; | ||
| } | ||
|
|
||
| /** | ||
| * Install rewrite rules to .htaccess files. | ||
| * | ||
| * @return bool True on success, false otherwise | ||
| */ | ||
| private static function install_rules() { | ||
| $rules = self::get_rewrite_rules(); | ||
|
|
||
| $upload_dir = wp_upload_dir(); | ||
| if ( isset( $upload_dir['basedir'] ) && is_writable( $upload_dir['basedir'] ) ) { | ||
| $htaccess_file = $upload_dir['basedir'] . '/.htaccess'; | ||
| insert_with_markers( $htaccess_file, self::MARKER, $rules ); | ||
| } | ||
|
|
||
| return true; | ||
| } | ||
|
|
||
| /** | ||
| * Remove rewrite rules from .htaccess files. | ||
| * | ||
| * @return bool True on success, false otherwise | ||
| */ | ||
| public static function uninstall_rules() { | ||
| $upload_dir = wp_upload_dir(); | ||
| if ( | ||
| file_exists( $upload_dir['basedir'] . '/.htaccess' ) | ||
| ) { | ||
| $htaccess_file = $upload_dir['basedir'] . '/.htaccess'; | ||
| insert_with_markers( $htaccess_file, self::MARKER, '' ); | ||
| } | ||
|
|
||
| return true; | ||
| } | ||
| } |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,87 @@ | ||
| <?php | ||
| /* | ||
| * Tiny Compress Images - WordPress plugin. | ||
| * Copyright (C) 2015-2018 Tinify B.V. | ||
| * | ||
| * This program is free software; you can redistribute it and/or modify it | ||
| * under the terms of the GNU General Public License as published by the Free | ||
| * Software Foundation; either version 2 of the License, or (at your option) | ||
| * any later version. | ||
| * | ||
| * This program is distributed in the hope that it will be useful, but WITHOUT | ||
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| * more details. | ||
| * | ||
| * You should have received a copy of the GNU General Public License along | ||
| * with this program; if not, write to the Free Software Foundation, Inc., 51 | ||
| * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| */ | ||
|
|
||
| /** | ||
| * class managing conversion delivery method | ||
| */ | ||
| class Tiny_Conversion extends Tiny_WP_Base { | ||
|
|
||
| /** | ||
| * @var Tiny_Settings plug-in settings | ||
| */ | ||
| private $settings; | ||
|
|
||
| /** | ||
| * @param Tiny_Settings $settings | ||
| */ | ||
| public function __construct( $settings ) { | ||
| parent::__construct(); | ||
| $this->settings = $settings; | ||
| } | ||
|
|
||
| /** | ||
| * will check if conversion is enabled, | ||
| * if true: | ||
| * - will enable the delivery method | ||
| * - will add hook to toggle rules | ||
| * | ||
| * hooked into `init` | ||
| */ | ||
| public function init() { | ||
| if ( ! $this->settings->get_conversion_enabled() ) { | ||
| return; | ||
| } | ||
|
|
||
| add_action( | ||
| 'update_option_tinypng_convert_format', | ||
| 'Tiny_Apache_Rewrite::toggle_rules', | ||
| 20, | ||
| 3 | ||
| ); | ||
|
|
||
| $delivery_method = $this->settings->get_conversion_delivery_method(); | ||
|
|
||
| $this->init_image_delivery( $delivery_method ); | ||
| } | ||
|
|
||
| /** | ||
| * Initializes the method of delivery for optimised images | ||
| * | ||
| * @param string $delivery_method 'picture' or 'htaccess' | ||
| * @return void | ||
| */ | ||
| private function init_image_delivery( $delivery_method ) { | ||
| /** | ||
| * Controls wether the page should replace <img> with <picture> elements | ||
| * converted sources. | ||
| * | ||
| * @since 3.7.0 | ||
| */ | ||
| if ( 'htaccess' === $delivery_method && Tiny_Server_Capabilities::is_apache() ) { | ||
| new Tiny_Apache_Rewrite(); | ||
| return; | ||
| } | ||
|
|
||
| if ( apply_filters( 'tiny_replace_with_picture', 'picture' === $delivery_method ) ) { | ||
| new Tiny_Picture( $this->settings, ABSPATH, array( get_site_url() ) ); | ||
| return; | ||
| } | ||
| } | ||
| } |
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,116 @@ | ||
| <?php | ||
| /* | ||
| * Tiny Compress Images - WordPress plugin. | ||
| * Copyright (C) 2015-2018 Tinify B.V. | ||
| * | ||
| * This program is free software; you can redistribute it and/or modify it | ||
| * under the terms of the GNU General Public License as published by the Free | ||
| * Software Foundation; either version 2 of the License, or (at your option) | ||
| * any later version. | ||
| * | ||
| * This program is distributed in the hope that it will be useful, but WITHOUT | ||
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| * more details. | ||
| * | ||
| * You should have received a copy of the GNU General Public License along | ||
| * with this program; if not, write to the Free Software Foundation, Inc., 51 | ||
| * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| */ | ||
|
|
||
| /** | ||
| * class responsible for checking and managing server capabilities | ||
| */ | ||
| class Tiny_Server_Capabilities { | ||
|
|
||
| /** | ||
| * Detect the web server software using WordPress globals. | ||
| * WordPress sets $is_apache, $is_IIS, $is_iis7, and $is_nginx in wp-includes/vars.php | ||
| * | ||
| * @return string The server type: 'apache', 'nginx', 'iis', or 'unknown' | ||
| */ | ||
| private static function get_server_type() { | ||
| global $is_apache, $is_iis7, $is_nginx; | ||
|
|
||
| if ( $is_apache ) { | ||
| return 'apache'; | ||
| } | ||
|
|
||
| if ( $is_nginx ) { | ||
| return 'nginx'; | ||
| } | ||
|
|
||
| if ( $is_iis7 ) { | ||
| return 'iis'; | ||
| } | ||
|
|
||
| return 'unknown'; | ||
| } | ||
|
|
||
| /** | ||
| * Check if the server is Apache. | ||
| * | ||
| * @return bool True if running on Apache | ||
| */ | ||
| public static function is_apache() { | ||
| return self::get_server_type() === 'apache'; | ||
| } | ||
|
|
||
| /** | ||
| * Check if mod_rewrite is available on Apache. | ||
| * | ||
| * @return bool True if mod_rewrite is available | ||
| */ | ||
| public static function has_mod_rewrite() { | ||
| if ( ! self::is_apache() ) { | ||
| return false; | ||
| } | ||
|
|
||
| if ( function_exists( 'apache_mod_loaded' ) ) { | ||
| return apache_mod_loaded( 'mod_rewrite' ); | ||
| } | ||
|
|
||
| if ( function_exists( 'apache_get_modules' ) ) { | ||
| $modules = apache_get_modules(); | ||
| return in_array( 'mod_rewrite', $modules, true ); | ||
| } | ||
|
|
||
| if ( function_exists( 'insert_with_markers' ) ) { | ||
| $htaccess = wp_upload_dir() . '.htaccess'; | ||
| return is_writable( dirname( $htaccess ) ); | ||
| } | ||
|
|
||
| return false; | ||
| } | ||
|
|
||
| /** | ||
| * Check if the /uploads directory is writable for .htaccess. | ||
| * | ||
| * @return bool True if uploads directory is writable, false otherwise | ||
| */ | ||
| public static function uploads_htaccess_writable() { | ||
| $upload_dir = wp_upload_dir(); | ||
| if ( isset( $upload_dir['basedir'] ) ) { | ||
| return is_writable( $upload_dir['basedir'] ); | ||
| } | ||
| return false; | ||
| } | ||
|
|
||
| /** | ||
| * Get a detailed capabilities object. | ||
| * | ||
| * @return array Array with properties: server, is_apache, has_mod_rewrite, | ||
| * uploads_writable, htaccess_available | ||
| */ | ||
| public static function get_capabilities() { | ||
| return array( | ||
| 'server' => self::get_server_type(), | ||
| 'is_apache' => self::is_apache(), | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we have is_apache seperately here. Can just as well call $is_apache in the code block where you use it |
||
| 'has_mod_rewrite' => self::has_mod_rewrite(), | ||
| 'uploads_writable' => self::uploads_htaccess_writable(), | ||
| 'htaccess_available' => self::is_apache() && | ||
| self::has_mod_rewrite() && | ||
| self::uploads_htaccess_writable(), | ||
| ); | ||
| } | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You miss is_caddy. it is a very small market share, so no big deal but maybe add it for completeness