| @@ -12,8 +12,9 @@ | ||
| 12 | 12 | defined( 'ABSPATH' ) || die( 'No direct script access allowed!' ); |
| 13 | 13 | |
| 14 | 14 | /** |
| 15 | 15 | * TablePress CSS Class |
| 16 | + * | |
| 16 | 17 | * @package TablePress |
| 17 | 18 | * @subpackage CSS |
| 18 | 19 | * @author Tobias Bäthge |
| 19 | 20 | * @since 1.1.0 |
| @@ -27,15 +28,13 @@ | ||
| 27 | 28 | * |
| 28 | 29 | * @param string $css CSS code. |
| 29 | 30 | * @return string Sanitized and tidied CSS code. |
| 30 | 31 | */ |
| 31 | - public function sanitize_css( $css ) { | |
| 32 | + public function sanitize_css( string $css ): string { | |
| 32 | 33 | $csstidy = TablePress::load_class( 'TablePress_CSSTidy', 'class.csstidy.php', 'libraries/csstidy' ); |
| 33 | 34 | |
| 34 | 35 | // Sanitization and not just tidying for users without enough privileges. |
| 35 | 36 | if ( ! current_user_can( 'unfiltered_html' ) ) { |
| 36 | - $csstidy->optimise = new TablePress_CSSTidy_custom_sanitize( $csstidy ); | |
| 37 | - | |
| 38 | 37 | // Let "arrows" survive, otherwise this might be recognized as the beginning of an HTML tag and removed with other stuff behind it. |
| 39 | 38 | $css = str_replace( '<=', '<=', $css ); |
| 40 | 39 | // Remove all HTML tags. |
| 41 | 40 | $css = wp_kses( $css, 'strip' ); |
| @@ -59,9 +58,9 @@ | ||
| 59 | 58 | $csstidy->set_cfg( 'merge_selectors', false ); |
| 60 | 59 | $csstidy->set_cfg( 'css_level', 'CSS3.0' ); |
| 61 | 60 | $csstidy->set_cfg( 'preserve_css', true ); |
| 62 | 61 | $csstidy->set_cfg( 'timestamp', false ); |
| 63 | - $csstidy->set_cfg( 'template', TABLEPRESS__DIR__ . '/libraries/csstidy/tablepress-standard.tpl' ); | |
| 62 | + $csstidy->set_cfg( 'template', 'default' ); | |
| 64 | 63 | |
| 65 | 64 | $csstidy->parse( $css ); |
| 66 | 65 | return $csstidy->print->plain(); |
| 67 | 66 | } |
| @@ -73,11 +72,10 @@ | ||
| 73 | 72 | * |
| 74 | 73 | * @param string $css CSS code. |
| 75 | 74 | * @return string Minified CSS code. |
| 76 | 75 | */ |
| 77 | - public function minify_css( $css ) { | |
| 76 | + public function minify_css( string $css ): string { | |
| 78 | 77 | $csstidy = TablePress::load_class( 'TablePress_CSSTidy', 'class.csstidy.php', 'libraries/csstidy' ); |
| 79 | - $csstidy->optimise = new TablePress_CSSTidy_custom_sanitize( $csstidy ); | |
| 80 | 78 | $csstidy->set_cfg( 'remove_bslash', false ); |
| 81 | 79 | $csstidy->set_cfg( 'compress_colors', true ); |
| 82 | 80 | $csstidy->set_cfg( 'compress_font-weight', true ); |
| 83 | 81 | $csstidy->set_cfg( 'lowercase_s', false ); |
| @@ -94,9 +92,12 @@ | ||
| 94 | 92 | $csstidy->set_cfg( 'timestamp', false ); |
| 95 | 93 | $csstidy->set_cfg( 'template', 'highest' ); |
| 96 | 94 | |
| 97 | 95 | $csstidy->parse( $css ); |
| 98 | - return $csstidy->print->plain(); | |
| 96 | + $css = $csstidy->print->plain(); | |
| 97 | + | |
| 98 | + // Remove all CSS comments from the minified CSS code, as CSSTidy does not remove those inside a CSS selector. | |
| 99 | + return preg_replace( '!/\*[^*]*\*+([^/][^*]*\*+)*/\n?!', '', $css ); | |
| 99 | 100 | } |
| 100 | 101 | |
| 101 | 102 | /** |
| 102 | 103 | * Get the location (file path or URL) of the "Custom CSS" file, depending on whether it's a Multisite install or not. |
| @@ -106,9 +107,9 @@ | ||
| 106 | 107 | * @param string $type "normal" version, "minified" version, or "combined" (with TablePress Default CSS) version. |
| 107 | 108 | * @param string $location "path" or "url", for file path or URL. |
| 108 | 109 | * @return string Full file path or full URL for the "Custom CSS" file. |
| 109 | 110 | */ |
| 110 | - public function get_custom_css_location( $type, $location ) { | |
| 111 | + public function get_custom_css_location( string $type, string $location ): string { | |
| 111 | 112 | switch ( $type ) { |
| 112 | 113 | case 'combined': |
| 113 | 114 | $file = 'tablepress-combined.min.css'; |
| 114 | 115 | break; |
| @@ -121,12 +122,12 @@ | ||
| 121 | 122 | break; |
| 122 | 123 | } |
| 123 | 124 | |
| 124 | 125 | if ( is_multisite() ) { |
| 125 | - // Multisite installation: /wp-content/uploads/sites/<ID>/ | |
| 126 | + // Multisite installation: Use /wp-content/uploads/sites/<ID>/. | |
| 126 | 127 | $upload_location = wp_upload_dir(); |
| 127 | 128 | } else { |
| 128 | - // Singlesite installation: /wp-content/ | |
| 129 | + // Singlesite installation: Use /wp-content/. | |
| 129 | 130 | $upload_location = array( |
| 130 | 131 | 'basedir' => WP_CONTENT_DIR, |
| 131 | 132 | 'baseurl' => content_url(), |
| 132 | 133 | ); |
| @@ -135,9 +136,9 @@ | ||
| 135 | 136 | switch ( $location ) { |
| 136 | 137 | case 'url': |
| 137 | 138 | $url = set_url_scheme( $upload_location['baseurl'] . '/' . $file ); |
| 138 | 139 | /** |
| 139 | - * Filter the URL from which the "Custom CSS" file is loaded. | |
| 140 | + * Filters the URL from which the "Custom CSS" file is loaded. | |
| 140 | 141 | * |
| 141 | 142 | * @since 1.0.0 |
| 142 | 143 | * |
| 143 | 144 | * @param string $url URL of the "Custom CSS" file. |
| @@ -145,13 +146,13 @@ | ||
| 145 | 146 | * @param string $type Type of the "Custom CSS" file ("normal", "minified", or "combined"). |
| 146 | 147 | */ |
| 147 | 148 | $url = apply_filters( 'tablepress_custom_css_url', $url, $file, $type ); |
| 148 | 149 | return $url; |
| 149 | - // break; // unreachable | |
| 150 | + // break; // unreachable. | |
| 150 | 151 | case 'path': |
| 151 | 152 | $path = $upload_location['basedir'] . '/' . $file; |
| 152 | 153 | /** |
| 153 | - * Filter the file path on the server from which the "Custom CSS" file is loaded. | |
| 154 | + * Filters the file path on the server from which the "Custom CSS" file is loaded. | |
| 154 | 155 | * |
| 155 | 156 | * @since 1.0.0 |
| 156 | 157 | * |
| 157 | 158 | * @param string $path File path of the "Custom CSS" file. |
| @@ -159,9 +160,13 @@ | ||
| 159 | 160 | * @param string $type Type of the "Custom CSS" file ("normal", "minified", or "combined"). |
| 160 | 161 | */ |
| 161 | 162 | $path = apply_filters( 'tablepress_custom_css_file_name', $path, $file, $type ); |
| 162 | 163 | return $path; |
| 163 | - // break; // unreachable | |
| 164 | + // break; // unreachable. | |
| 165 | + default: | |
| 166 | + // Return an empty string if no valid location was provided. | |
| 167 | + return ''; | |
| 168 | + // break; // unreachable. | |
| 164 | 169 | } |
| 165 | 170 | } |
| 166 | 171 | |
| 167 | 172 | /** |
| @@ -169,20 +174,20 @@ | ||
| 169 | 174 | * |
| 170 | 175 | * @since 1.0.0 |
| 171 | 176 | * |
| 172 | 177 | * @param string $type Optional. Whether to load "normal" version or "minified" version. Default "normal". |
| 173 | - * @return string|bool Custom CSS on success, false on error. | |
| 178 | + * @return string|false Custom CSS on success, false on error. | |
| 174 | 179 | */ |
| 175 | - public function load_custom_css_from_file( $type = 'normal' ) { | |
| 180 | + public function load_custom_css_from_file( string $type = 'normal' ) /* : string|false */ { | |
| 176 | 181 | $filename = $this->get_custom_css_location( $type, 'path' ); |
| 177 | 182 | // Check if file name is valid (0 means yes). |
| 178 | 183 | if ( 0 !== validate_file( $filename ) ) { |
| 179 | 184 | return false; |
| 180 | 185 | } |
| 181 | - if ( ! @is_file( $filename ) ) { | |
| 186 | + if ( ! @is_file( $filename ) ) { // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged | |
| 182 | 187 | return false; |
| 183 | 188 | } |
| 184 | - if ( ! @is_readable( $filename ) ) { | |
| 189 | + if ( ! @is_readable( $filename ) ) { // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged | |
| 185 | 190 | return false; |
| 186 | 191 | } |
| 187 | 192 | return file_get_contents( $filename ); |
| 188 | 193 | } |
| @@ -187,24 +192,28 @@ | ||
| 187 | 192 | return file_get_contents( $filename ); |
| 188 | 193 | } |
| 189 | 194 | |
| 190 | 195 | /** |
| 191 | - * Load the contents of the file with the TablePress Default CSS. | |
| 196 | + * Loads the contents of the file with the TablePress Default CSS, | |
| 197 | + * either for left-to-right (LTR) or right-to-left (RTL), in minified form. | |
| 192 | 198 | * |
| 193 | 199 | * @since 1.1.0 |
| 200 | + * @since 2.0.0 Added the `$load_rtl` parameter. | |
| 194 | 201 | * |
| 195 | - * @return string|bool TablePress Default CSS on success, false on error. | |
| 202 | + * @param bool $load_rtl Optional. Whether to load LTR or RTL version. Default LTR. | |
| 203 | + * @return string|false TablePress Default CSS on success, false on error. | |
| 196 | 204 | */ |
| 197 | - public function load_default_css_from_file() { | |
| 198 | - $filename = TABLEPRESS_ABSPATH . 'css/default.min.css'; | |
| 205 | + public function load_default_css_from_file( bool $load_rtl = false ) /* : string|false */ { | |
| 206 | + $rtl = $load_rtl ? '-rtl' : ''; | |
| 207 | + $filename = TABLEPRESS_ABSPATH . "css/build/default{$rtl}.css"; | |
| 199 | 208 | // Check if file name is valid (0 means yes). |
| 200 | 209 | if ( 0 !== validate_file( $filename ) ) { |
| 201 | 210 | return false; |
| 202 | 211 | } |
| 203 | - if ( ! @is_file( $filename ) ) { | |
| 212 | + if ( ! @is_file( $filename ) ) { // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged | |
| 204 | 213 | return false; |
| 205 | 214 | } |
| 206 | - if ( ! @is_readable( $filename ) ) { | |
| 215 | + if ( ! @is_readable( $filename ) ) { // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged | |
| 207 | 216 | return false; |
| 208 | 217 | } |
| 209 | 218 | return file_get_contents( $filename ); |
| 210 | 219 | } |
| @@ -217,11 +226,11 @@ | ||
| 217 | 226 | * @param string $custom_css_normal Custom CSS code to be saved. |
| 218 | 227 | * @param string $custom_css_minified Minified CSS code to be saved. |
| 219 | 228 | * @return bool True on success, false on failure. |
| 220 | 229 | */ |
| 221 | - public function save_custom_css_to_file( $custom_css_normal, $custom_css_minified ) { | |
| 230 | + public function save_custom_css_to_file( string $custom_css_normal, string $custom_css_minified ): bool { | |
| 222 | 231 | /** |
| 223 | - * Filter whether the "Custom CSS" code shall be saved to a file on the server. | |
| 232 | + * Filters whether the "Custom CSS" code shall be saved to a file on the server. | |
| 224 | 233 | * |
| 225 | 234 | * @since 1.1.0 |
| 226 | 235 | * |
| 227 | 236 | * @param bool $save Whether to save the "Custom CSS" to a file. Default true. |
| @@ -231,14 +240,15 @@ | ||
| 231 | 240 | } |
| 232 | 241 | |
| 233 | 242 | // Start capturing the output, to later prevent it. |
| 234 | 243 | ob_start(); |
| 235 | - $credentials = request_filesystem_credentials( '', '', false, false, null ); | |
| 244 | + $credentials = request_filesystem_credentials( '', '', false, '', null, false ); | |
| 245 | + | |
| 236 | 246 | /* |
| 237 | 247 | * Do we have credentials already? (Otherwise the form will have been rendered, which is not supported here.) |
| 238 | 248 | * Or, if we have credentials, are they valid? |
| 239 | 249 | */ |
| 240 | - if ( false === $credentials || ! WP_Filesystem( $credentials ) ) { | |
| 250 | + if ( false === $credentials || ! WP_Filesystem( $credentials ) ) { // @phpstan-ignore argument.type | |
| 241 | 251 | ob_end_clean(); |
| 242 | 252 | return false; |
| 243 | 253 | } |
| 244 | 254 | |
| @@ -256,9 +266,9 @@ | ||
| 256 | 266 | * @param string $custom_css_normal Custom CSS code to be saved. If empty, files will be deleted. |
| 257 | 267 | * @param string $custom_css_minified Minified CSS code to be saved. |
| 258 | 268 | * @return bool|string True on success, false on failure, or string of HTML for the credentials form for the WP_Filesystem API, if necessary. |
| 259 | 269 | */ |
| 260 | - public function save_custom_css_to_file_plugin_options( $custom_css_normal, $custom_css_minified ) { | |
| 270 | + public function save_custom_css_to_file_plugin_options( string $custom_css_normal, string $custom_css_minified ) /* : bool|string */ { | |
| 261 | 271 | /** This filter is documented in classes/class-css.php */ |
| 262 | 272 | if ( ! apply_filters( 'tablepress_save_custom_css_to_file', true ) ) { |
| 263 | 273 | return false; |
| 264 | 274 | } |
| @@ -264,22 +274,22 @@ | ||
| 264 | 274 | } |
| 265 | 275 | |
| 266 | 276 | // Start capturing the output, to get HTML of the credentials form (if needed). |
| 267 | 277 | ob_start(); |
| 268 | - $credentials = request_filesystem_credentials( '', '', false, false, null ); | |
| 269 | - // Do we have credentials already? (Otherwise the form will have been rendered already.) | |
| 278 | + $credentials = request_filesystem_credentials( '', '', false, '', null, false ); | |
| 279 | + // Do we have credentials already? Otherwise the form will have been rendered already. | |
| 270 | 280 | if ( false === $credentials ) { |
| 271 | 281 | $form_data = ob_get_clean(); |
| 272 | - $form_data = str_replace( 'name="upgrade" id="upgrade" class="button"', 'name="upgrade" id="upgrade" class="button button-primary button-large"', $form_data ); | |
| 282 | + $form_data = str_replace( 'name="upgrade" id="upgrade" class="button"', 'name="upgrade" id="upgrade" class="components-button is-primary"', $form_data ); // @phpstan-ignore argument.type | |
| 273 | 283 | return $form_data; |
| 274 | 284 | } |
| 275 | 285 | |
| 276 | 286 | // We have received credentials, but don't know if they are valid yet. |
| 277 | - if ( ! WP_Filesystem( $credentials ) ) { | |
| 287 | + if ( ! WP_Filesystem( $credentials ) ) { // @phpstan-ignore argument.type | |
| 278 | 288 | // Credentials failed, so ask again (with $error flag true). |
| 279 | - request_filesystem_credentials( '', '', true, false, null ); | |
| 289 | + request_filesystem_credentials( '', '', true, '', null, false ); | |
| 280 | 290 | $form_data = ob_get_clean(); |
| 281 | - $form_data = str_replace( 'name="upgrade" id="upgrade" class="button"', 'name="upgrade" id="upgrade" class="button button-primary button-large"', $form_data ); | |
| 291 | + $form_data = str_replace( 'name="upgrade" id="upgrade" class="button"', 'name="upgrade" id="upgrade" class="components-button is-primary"', $form_data ); // @phpstan-ignore argument.type | |
| 282 | 292 | return $form_data; |
| 283 | 293 | } |
| 284 | 294 | |
| 285 | 295 | // We have valid access to the filesystem now -> try to save the files, or delete them if the "Custom CSS" is empty. |
| @@ -304,9 +314,9 @@ | ||
| 304 | 314 | * @param string $custom_css_normal Custom CSS code to be saved. |
| 305 | 315 | * @param string $custom_css_minified Minified CSS code to be saved. |
| 306 | 316 | * @return bool True on success, false on failure. |
| 307 | 317 | */ |
| 308 | - protected function _custom_css_save_helper( $custom_css_normal, $custom_css_minified ) { | |
| 318 | + protected function _custom_css_save_helper( string $custom_css_normal, string $custom_css_minified ): bool { | |
| 309 | 319 | global $wp_filesystem; |
| 310 | 320 | |
| 311 | 321 | /* |
| 312 | 322 | * WP_CONTENT_DIR and (FTP-)Content-Dir can be different (e.g. if FTP working dir is /). |
| @@ -315,25 +325,19 @@ | ||
| 315 | 325 | $path_difference = str_replace( $wp_filesystem->wp_content_dir(), '', trailingslashit( WP_CONTENT_DIR ) ); |
| 316 | 326 | |
| 317 | 327 | $css_types = array( 'normal', 'minified', 'combined' ); |
| 318 | 328 | |
| 319 | - $default_css = $this->load_default_css_from_file(); | |
| 320 | - if ( false === $default_css ) { | |
| 321 | - $default_css = ''; | |
| 322 | - } else { | |
| 323 | - // Change relative URLs to web font files to absolute URLs, as combining the CSS files and saving to another directory breaks the relative URLs. | |
| 324 | - $absolute_path = plugins_url( 'css/tablepress.', TABLEPRESS__FILE__ ); | |
| 325 | - // Make the absolute URL protocol-relative to prevent mixed content warnings. | |
| 326 | - $absolute_path = str_replace( array( 'http:', 'https:' ), '', $absolute_path ); | |
| 327 | - $default_css = str_replace( 'url(tablepress.', 'url(' . $absolute_path, $default_css ); | |
| 329 | + $default_css_minified = $this->load_default_css_from_file( false ); | |
| 330 | + if ( false === $default_css_minified ) { | |
| 331 | + $default_css_minified = ''; | |
| 328 | 332 | } |
| 329 | 333 | $file_content = array( |
| 330 | 334 | 'normal' => $custom_css_normal, |
| 331 | 335 | 'minified' => $custom_css_minified, |
| 332 | - 'combined' => $default_css . "\n" . $custom_css_minified, | |
| 336 | + 'combined' => $default_css_minified . $custom_css_minified, | |
| 333 | 337 | ); |
| 334 | 338 | |
| 335 | - $total_result = true; // whether all files were saved successfully | |
| 339 | + $total_result = true; // Whether all files were saved successfully. | |
| 336 | 340 | foreach ( $css_types as $css_type ) { |
| 337 | 341 | $filename = $this->get_custom_css_location( $css_type, 'path' ); |
| 338 | 342 | // Check if filename is valid (0 means yes). |
| 339 | 343 | if ( 0 !== validate_file( $filename ) ) { |
| @@ -358,17 +362,18 @@ | ||
| 358 | 362 | * @since 1.0.0 |
| 359 | 363 | * |
| 360 | 364 | * @return bool True on success, false on failure. |
| 361 | 365 | */ |
| 362 | - public function delete_custom_css_files() { | |
| 366 | + public function delete_custom_css_files(): bool { | |
| 363 | 367 | // Start capturing the output, to later prevent it. |
| 364 | 368 | ob_start(); |
| 365 | - $credentials = request_filesystem_credentials( '', '', false, false, null ); | |
| 369 | + $credentials = request_filesystem_credentials( '', '', false, '', null, false ); | |
| 370 | + | |
| 366 | 371 | /* |
| 367 | 372 | * Do we have credentials already? (Otherwise the form will have been rendered, which is not supported here.) |
| 368 | 373 | * Or, if we have credentials, are they valid? |
| 369 | 374 | */ |
| 370 | - if ( false === $credentials || ! WP_Filesystem( $credentials ) ) { | |
| 375 | + if ( false === $credentials || ! WP_Filesystem( $credentials ) ) { // @phpstan-ignore argument.type | |
| 371 | 376 | ob_end_clean(); |
| 372 | 377 | return false; |
| 373 | 378 | } |
| 374 | 379 | |
| @@ -388,9 +393,9 @@ | ||
| 388 | 393 | * @see save_custom_css_to_file_plugin_options() |
| 389 | 394 | * |
| 390 | 395 | * @return bool True on success, false on failure. |
| 391 | 396 | */ |
| 392 | - protected function _custom_css_delete_helper() { | |
| 397 | + protected function _custom_css_delete_helper(): bool { | |
| 393 | 398 | global $wp_filesystem; |
| 394 | 399 | |
| 395 | 400 | /* |
| 396 | 401 | * WP_CONTENT_DIR and (FTP-)Content-Dir can be different (e.g. if FTP working dir is /). |
| @@ -398,9 +403,9 @@ | ||
| 398 | 403 | */ |
| 399 | 404 | $path_difference = str_replace( $wp_filesystem->wp_content_dir(), '', trailingslashit( WP_CONTENT_DIR ) ); |
| 400 | 405 | |
| 401 | 406 | $css_types = array( 'normal', 'minified', 'combined' ); |
| 402 | - $total_result = true; // whether all files were deleted successfully | |
| 407 | + $total_result = true; // Whether all files were deleted successfully. | |
| 403 | 408 | foreach ( $css_types as $css_type ) { |
| 404 | 409 | $filename = $this->get_custom_css_location( $css_type, 'path' ); |
| 405 | 410 | // Check if filename is valid (0 means yes). |
| 406 | 411 | if ( 0 !== validate_file( $filename ) ) { |
| @@ -422,25 +427,25 @@ | ||
| 422 | 427 | return $total_result; |
| 423 | 428 | } |
| 424 | 429 | |
| 425 | 430 | /** |
| 426 | - * Flush the CSS minification cache of W3 Total Cache. | |
| 431 | + * Flush the CSS minification caches of common caching plugins. | |
| 427 | 432 | * |
| 428 | 433 | * @since 1.4.0 |
| 429 | 434 | */ |
| 430 | - protected function _flush_caching_plugins_css_minify_caches() { | |
| 435 | + protected function _flush_caching_plugins_css_minify_caches(): void { | |
| 431 | 436 | /** This filter is documented in models/model-table.php */ |
| 432 | 437 | if ( ! apply_filters( 'tablepress_flush_caching_plugins_caches', true ) ) { |
| 433 | 438 | return; |
| 434 | 439 | } |
| 435 | 440 | |
| 436 | - // W3 Total Cache | |
| 441 | + // W3 Total Cache. | |
| 437 | 442 | if ( function_exists( 'w3tc_minify_flush' ) ) { |
| 438 | 443 | w3tc_minify_flush(); |
| 439 | 444 | } |
| 440 | - // WP Fastest Cache | |
| 441 | - if ( isset( $GLOBALS['wp_fastest_cache'] ) && method_exists( $GLOBALS['wp_fastest_cache'], 'deleteCache' ) ) { | |
| 442 | - $GLOBALS['wp_fastest_cache']->deleteCache( true ); | |
| 445 | + // WP Fastest Cache. | |
| 446 | + if ( isset( $GLOBALS['wp_fastest_cache'] ) && is_callable( array( $GLOBALS['wp_fastest_cache'], 'deleteCache' ) ) ) { | |
| 447 | + $GLOBALS['wp_fastest_cache']->deleteCache( true ); // @phpstan-ignore method.nonObject | |
| 443 | 448 | } |
| 444 | 449 | } |
| 445 | 450 | |
| 446 | 451 | } // class TablePress_CSS |