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