compatibility
5 months ago
config
5 months ago
css
5 months ago
data
3 years ago
images
3 years ago
js
5 months ago
vendor
4 months ago
views
2 months ago
class-tiny-apache-rewrite.php
2 months ago
class-tiny-bulk-optimization.php
5 months ago
class-tiny-cli.php
5 months ago
class-tiny-compress-client.php
5 months ago
class-tiny-compress-fopen.php
5 months ago
class-tiny-compress.php
5 months ago
class-tiny-conversion.php
2 months ago
class-tiny-diagnostics.php
5 months ago
class-tiny-exception.php
5 months ago
class-tiny-helpers.php
5 months ago
class-tiny-image-size.php
5 months ago
class-tiny-image.php
5 months ago
class-tiny-logger.php
2 months ago
class-tiny-notices.php
2 months ago
class-tiny-php.php
5 months ago
class-tiny-picture.php
4 months ago
class-tiny-plugin.php
2 months ago
class-tiny-settings.php
2 months ago
class-tiny-source-base.php
2 months ago
class-tiny-source-image.php
5 months ago
class-tiny-source-picture.php
5 months ago
class-tiny-wp-base.php
5 months ago
class-tiny-apache-rewrite.php
166 lines
| 1 | <?php |
| 2 | /* |
| 3 | * Tiny Compress Images - WordPress plugin. |
| 4 | * Copyright (C) 2015-2018 Tinify B.V. |
| 5 | * |
| 6 | * This program is free software; you can redistribute it and/or modify it |
| 7 | * under the terms of the GNU General Public License as published by the Free |
| 8 | * Software Foundation; either version 2 of the License, or (at your option) |
| 9 | * any later version. |
| 10 | * |
| 11 | * This program is distributed in the hope that it will be useful, but WITHOUT |
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
| 14 | * more details. |
| 15 | * |
| 16 | * You should have received a copy of the GNU General Public License along |
| 17 | * with this program; if not, write to the Free Software Foundation, Inc., 51 |
| 18 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n*/ |
| 19 | |
| 20 | /** |
| 21 | * Tiny_Apache_Rewrite |
| 22 | * class responsible for the apache rules for image delivery. |
| 23 | * - toggling the rules when saving settings |
| 24 | * - inserting/removing rules from htaccess |
| 25 | * |
| 26 | * We are only updating rules when: |
| 27 | * - updating the option convert_format |
| 28 | * - uninstalling the plug-in |
| 29 | */ |
| 30 | class Tiny_Apache_Rewrite extends Tiny_WP_Base { |
| 31 | |
| 32 | /** |
| 33 | * seperator when rules are inserted |
| 34 | * @var string |
| 35 | */ |
| 36 | const MARKER = 'tiny-compress-images'; |
| 37 | |
| 38 | /** |
| 39 | * Installs or uninstalls the htaccess rules |
| 40 | * hooked into `update_option_tinypng_convert_format` |
| 41 | * https://developer.wordpress.org/reference/hooks/update_option_option/ |
| 42 | * |
| 43 | * |
| 44 | * @param mixed $old_value |
| 45 | * @param mixed $value |
| 46 | * @param string $option |
| 47 | * @return void |
| 48 | */ |
| 49 | public static function toggle_rules( $old_value, $value, $option ) { |
| 50 | $old_delivery = isset( $old_value['delivery_method'] ) ? |
| 51 | $old_value['delivery_method'] : null; |
| 52 | $new_delivery = isset( $value['delivery_method'] ) ? |
| 53 | $value['delivery_method'] : null; |
| 54 | |
| 55 | if ( $old_delivery === $new_delivery ) { |
| 56 | return; |
| 57 | } |
| 58 | |
| 59 | if ( 'htaccess' === $new_delivery ) { |
| 60 | $installed = self::install_rules(); |
| 61 | Tiny_Logger::debug( 'htaccess rules installed: ' . $installed ); |
| 62 | return; |
| 63 | } |
| 64 | |
| 65 | // We only uninstall if we were previously using htaccess |
| 66 | if ( 'htaccess' === $old_delivery ) { |
| 67 | $uninstalled = self::uninstall_rules(); |
| 68 | Tiny_Logger::debug( 'htaccess rules uninstaled: ' . $uninstalled ); |
| 69 | } |
| 70 | } |
| 71 | |
| 72 | /** |
| 73 | * Generate .htaccess rewrite rules for serving WebP and AVIF images. |
| 74 | * |
| 75 | * @return string The .htaccess rules |
| 76 | */ |
| 77 | private static function get_rewrite_rules() { |
| 78 | $rules = array(); |
| 79 | $rules[] = '<IfModule mod_rewrite.c>'; |
| 80 | $rules[] = 'RewriteEngine On'; |
| 81 | $rules[] = 'RewriteOptions Inherit'; |
| 82 | |
| 83 | $rules = array_merge( $rules, self::get_avif_rules() ); |
| 84 | $rules = array_merge( $rules, self::get_webp_rules() ); |
| 85 | |
| 86 | $rules[] = '</IfModule>'; |
| 87 | |
| 88 | $rules[] = '<IfModule mod_headers.c>'; |
| 89 | $rules[] = '<FilesMatch "\.(jpe?g|png)$">'; |
| 90 | $rules[] = 'Header append Vary Accept'; |
| 91 | $rules[] = '</FilesMatch>'; |
| 92 | $rules[] = '</IfModule>'; |
| 93 | |
| 94 | $rules[] = '<IfModule mod_mime.c>'; |
| 95 | $rules[] = 'AddType image/webp .webp'; |
| 96 | $rules[] = 'AddType image/avif .avif'; |
| 97 | $rules[] = '</IfModule>'; |
| 98 | |
| 99 | return implode( "\n", $rules ); |
| 100 | } |
| 101 | |
| 102 | /** |
| 103 | * Generate AVIF rewrite rules. |
| 104 | * |
| 105 | * @return array[] AVIF rewrite rules |
| 106 | */ |
| 107 | private static function get_avif_rules() { |
| 108 | $rules = array(); |
| 109 | $rules[] = 'RewriteCond %{HTTP_ACCEPT} image/avif'; |
| 110 | $rules[] = 'RewriteCond %{REQUEST_URI} ^(.+)\.(?:jpe?g|png)$'; |
| 111 | $rules[] = 'RewriteCond %{DOCUMENT_ROOT}/%1.avif -f'; |
| 112 | $rules[] = 'RewriteCond %{QUERY_STRING} !type=original'; |
| 113 | $rules[] = 'RewriteRule (.+)\.(?:jpe?g|png)$ $1.avif [T=image/avif,L]'; |
| 114 | return $rules; |
| 115 | } |
| 116 | |
| 117 | /** |
| 118 | * Generate WebP rewrite rules. |
| 119 | * |
| 120 | * @return array[] WebP rewrite rules |
| 121 | */ |
| 122 | private static function get_webp_rules() { |
| 123 | $rules = array(); |
| 124 | $rules[] = 'RewriteCond %{HTTP_ACCEPT} image/webp'; |
| 125 | $rules[] = 'RewriteCond %{REQUEST_URI} ^(.+)\.(?:jpe?g|png)$'; |
| 126 | $rules[] = 'RewriteCond %{DOCUMENT_ROOT}/%1.webp -f'; |
| 127 | $rules[] = 'RewriteCond %{QUERY_STRING} !type=original'; |
| 128 | $rules[] = 'RewriteRule (.+)\.(?:jpe?g|png)$ $1.webp [T=image/webp,L]'; |
| 129 | |
| 130 | return $rules; |
| 131 | } |
| 132 | |
| 133 | /** |
| 134 | * Install rewrite rules to .htaccess files. |
| 135 | * |
| 136 | * @return bool True on success, false otherwise |
| 137 | */ |
| 138 | private static function install_rules() { |
| 139 | $rules = self::get_rewrite_rules(); |
| 140 | $upload_dir = wp_upload_dir(); |
| 141 | if ( isset( $upload_dir['basedir'] ) && is_writable( $upload_dir['basedir'] ) ) { |
| 142 | $htaccess_file = $upload_dir['basedir'] . '/.htaccess'; |
| 143 | return insert_with_markers( $htaccess_file, self::MARKER, $rules ); |
| 144 | } |
| 145 | |
| 146 | return false; |
| 147 | } |
| 148 | |
| 149 | /** |
| 150 | * Remove rewrite rules from .htaccess files. |
| 151 | * |
| 152 | * @return bool True on success, false otherwise |
| 153 | */ |
| 154 | public static function uninstall_rules() { |
| 155 | $upload_dir = wp_upload_dir(); |
| 156 | if ( |
| 157 | file_exists( $upload_dir['basedir'] . '/.htaccess' ) |
| 158 | ) { |
| 159 | $htaccess_file = $upload_dir['basedir'] . '/.htaccess'; |
| 160 | return insert_with_markers( $htaccess_file, self::MARKER, '' ); |
| 161 | } |
| 162 | |
| 163 | return false; |
| 164 | } |
| 165 | } |
| 166 |