Version Description
[2022.01.31] = * WP 5.9 / PHP 8 maintenance release * changed deferred css/js cache clearing from 24h to 7 days * added cache purging support for nginx helper plugin * added option to allow processing on specific query strings * other bug fixes
Download this release
Release Info
Developer | Alignak |
Plugin | Fast Velocity Minify |
Version | 3.2.4 |
Comparing to | |
See all releases |
Code changes from version 3.2.2 to 3.2.4
- fvm.php +1 -1
- inc/admin.php +124 -56
- inc/common.php +228 -83
- inc/frontend.php +3 -3
- layout/admin-layout-help.php +15 -0
- layout/admin-layout-settings.php +19 -3
- libs/matthiasmullie/minify/src/CSS.php +1 -41
- libs/simplehtmldom/simple_html_dom.php +129 -129
- readme.txt +14 -4
fvm.php
CHANGED
@@ -6,7 +6,7 @@ Description: Improve your speed score on GTmetrix, Pingdom Tools and Google Page
|
|
6 |
Author: Raul Peixoto
|
7 |
Author URI: http://fastvelocity.com
|
8 |
Text Domain: fast-velocity-minify
|
9 |
-
Version: 3.2.
|
10 |
License: GPL2
|
11 |
|
12 |
------------------------------------------------------------------------
|
6 |
Author: Raul Peixoto
|
7 |
Author URI: http://fastvelocity.com
|
8 |
Text Domain: fast-velocity-minify
|
9 |
+
Version: 3.2.4
|
10 |
License: GPL2
|
11 |
|
12 |
------------------------------------------------------------------------
|
inc/admin.php
CHANGED
@@ -83,6 +83,49 @@ function fvm_check_misconfiguration() {
|
|
83 |
}
|
84 |
|
85 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
86 |
|
87 |
} catch (Exception $e) {
|
88 |
error_log('Caught exception (fvm_initialize_database): '.$e->getMessage(), 0);
|
@@ -207,25 +250,30 @@ function fvm_add_admin_menu() {
|
|
207 |
# print admin notices when needed (json)
|
208 |
function fvm_show_admin_notice_from_transient() {
|
209 |
if(current_user_can('manage_options')) {
|
210 |
-
$inf = get_transient('
|
|
|
|
|
211 |
if($inf != false && !empty($inf)) {
|
212 |
-
$
|
213 |
-
if(!is_null($
|
214 |
-
|
215 |
-
# add all
|
216 |
-
$jsonarr = array_unique($jsonarr);
|
217 |
-
foreach ($jsonarr as $notice) {
|
218 |
-
add_settings_error( 'fvm_admin_notice', 'fvm_admin_notice', 'FVM: '.$notice, 'info' );
|
219 |
-
}
|
220 |
|
221 |
-
#
|
222 |
-
|
223 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
224 |
}
|
|
|
225 |
}
|
226 |
|
227 |
-
#
|
228 |
-
delete_transient('
|
|
|
229 |
}
|
230 |
}
|
231 |
}
|
@@ -301,47 +349,66 @@ function fvm_get_logs_callback() {
|
|
301 |
register_activation_hook($fvm_var_file, 'fvm_plugin_activate');
|
302 |
function fvm_plugin_activate() {
|
303 |
|
|
|
304 |
global $wpdb;
|
305 |
if(is_null($wpdb)) { return false; }
|
306 |
-
|
307 |
-
# defauls
|
308 |
-
$sql = array();
|
309 |
-
$wpdb_collate = $wpdb->collate;
|
310 |
-
|
311 |
-
# create cache table
|
312 |
$sqla_table_name = $wpdb->prefix . 'fvm_cache';
|
313 |
-
$sqla = "CREATE TABLE IF NOT EXISTS {$sqla_table_name} (
|
314 |
-
`id` bigint(20) unsigned NOT NULL auto_increment ,
|
315 |
-
`uid` varchar(64) NOT NULL,
|
316 |
-
`date` bigint(10) unsigned NOT NULL,
|
317 |
-
`type` varchar(3) NOT NULL,
|
318 |
-
`content` mediumtext NOT NULL,
|
319 |
-
`meta` mediumtext NOT NULL,
|
320 |
-
PRIMARY KEY (id),
|
321 |
-
UNIQUE KEY uid (uid),
|
322 |
-
KEY date (date), KEY type (type)
|
323 |
-
)
|
324 |
-
COLLATE {$wpdb_collate}";
|
325 |
-
|
326 |
-
# create logs table
|
327 |
$sqlb_table_name = $wpdb->prefix . 'fvm_logs';
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
341 |
|
342 |
# run sql
|
343 |
-
|
344 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
345 |
|
346 |
}
|
347 |
|
@@ -349,6 +416,9 @@ function fvm_plugin_activate() {
|
|
349 |
# run during deactivation
|
350 |
register_deactivation_hook($fvm_var_file, 'fvm_plugin_deactivate');
|
351 |
function fvm_plugin_deactivate() {
|
|
|
|
|
|
|
352 |
|
353 |
global $wpdb;
|
354 |
if(is_null($wpdb)) { return false; }
|
@@ -356,16 +426,17 @@ function fvm_plugin_deactivate() {
|
|
356 |
# remove options and tables
|
357 |
$wpdb->query("DELETE FROM {$wpdb->prefix}options WHERE option_name = 'fvm_last_cache_update'");
|
358 |
$wpdb->query("DROP TABLE IF EXISTS {$wpdb->prefix}fvm_cache");
|
359 |
-
$wpdb->query("DROP TABLE IF EXISTS {$wpdb->prefix}fvm_logs");
|
360 |
-
|
361 |
-
# process cache settings
|
362 |
-
fvm_purge_static_files();
|
363 |
|
364 |
}
|
365 |
|
366 |
# run during uninstall
|
367 |
register_uninstall_hook($fvm_var_file, 'fvm_plugin_uninstall');
|
368 |
function fvm_plugin_uninstall() {
|
|
|
|
|
|
|
|
|
369 |
global $wpdb;
|
370 |
if(is_null($wpdb)) { return false; }
|
371 |
|
@@ -375,9 +446,6 @@ function fvm_plugin_uninstall() {
|
|
375 |
$wpdb->query("DROP TABLE IF EXISTS {$wpdb->prefix}fvm_cache");
|
376 |
$wpdb->query("DROP TABLE IF EXISTS {$wpdb->prefix}fvm_logs");
|
377 |
|
378 |
-
# process cache settings
|
379 |
-
fvm_purge_static_files();
|
380 |
-
|
381 |
}
|
382 |
|
383 |
|
83 |
}
|
84 |
|
85 |
}
|
86 |
+
|
87 |
+
# check if our tables exist, and do maintenance once a day
|
88 |
+
$fvm_table_checker = get_transient('fvm_table_checker');
|
89 |
+
$fvm_table_checker = false;
|
90 |
+
if ($fvm_table_checker === false) {
|
91 |
+
|
92 |
+
# test if at least one table exists
|
93 |
+
global $wpdb;
|
94 |
+
if(!is_null($wpdb)) {
|
95 |
+
$sqla_table_name = $wpdb->prefix . 'fvm_cache';
|
96 |
+
if (!$wpdb->get_var($wpdb->prepare("SHOW TABLES LIKE %s", $sqla_table_name)) === $sqla_table_name) {
|
97 |
+
fvm_plugin_activate();
|
98 |
+
}
|
99 |
+
}
|
100 |
+
|
101 |
+
# daily maintenance
|
102 |
+
try {
|
103 |
+
|
104 |
+
if(!is_null($wpdb)) {
|
105 |
+
|
106 |
+
# limit cache table to 20k records
|
107 |
+
$lim = 20000;
|
108 |
+
$res = $wpdb->get_row("SELECT MAX(id) as maxid FROM ".$wpdb->prefix."fvm_cache");
|
109 |
+
if(isset($res->maxid) && intval($res->maxid) > $lim) {
|
110 |
+
$wpdb->query($wpdb->prepare("DELETE FROM ".$wpdb->prefix."fvm_cache WHERE id < %d LIMIT 1", (intval($res->maxid) - $lim)));
|
111 |
+
}
|
112 |
+
|
113 |
+
# limit logs table to 500 records
|
114 |
+
$lim = 500;
|
115 |
+
$res = $wpdb->get_row("SELECT MAX(id) as maxid FROM ".$wpdb->prefix."fvm_logs");
|
116 |
+
if(isset($res->maxid) && intval($res->maxid) > $lim) {
|
117 |
+
$wpdb->query($wpdb->prepare("DELETE FROM ".$wpdb->prefix."fvm_logs WHERE id < %d LIMIT 1", (intval($res->maxid) - $lim)));
|
118 |
+
}
|
119 |
+
|
120 |
+
}
|
121 |
+
|
122 |
+
} catch (Exception $e) {
|
123 |
+
error_log('Error: '.$e->getMessage(), 0);
|
124 |
+
}
|
125 |
+
|
126 |
+
|
127 |
+
}
|
128 |
+
|
129 |
|
130 |
} catch (Exception $e) {
|
131 |
error_log('Caught exception (fvm_initialize_database): '.$e->getMessage(), 0);
|
250 |
# print admin notices when needed (json)
|
251 |
function fvm_show_admin_notice_from_transient() {
|
252 |
if(current_user_can('manage_options')) {
|
253 |
+
$inf = get_transient('fvm_admin_notice_'.get_current_user_id());
|
254 |
+
|
255 |
+
# show transient after the redirect
|
256 |
if($inf != false && !empty($inf)) {
|
257 |
+
$notices = json_decode($inf, true);
|
258 |
+
if(!is_null($notices) && is_array($notices)){
|
|
|
|
|
|
|
|
|
|
|
|
|
259 |
|
260 |
+
# consolidate messages
|
261 |
+
$notices = array_unique($notices);
|
262 |
+
if(count($notices) > 1) {
|
263 |
+
$msg = '<div class="fvm-info-list"><h3>FVM</h3><ul>';
|
264 |
+
foreach ($notices as $notice) { $msg.= "<li>$notice</li>"; }
|
265 |
+
$msg.= '</ul></div>';
|
266 |
+
add_settings_error( 'fvm_admin_notice', 'fvm_admin_notice', $msg, 'info' );
|
267 |
+
} else {
|
268 |
+
$msg = 'FVM: '.implode(PHP_EOL, $notices);
|
269 |
+
add_settings_error( 'fvm_admin_notice', 'fvm_admin_notice', $msg, 'info' );
|
270 |
}
|
271 |
+
|
272 |
}
|
273 |
|
274 |
+
# delete
|
275 |
+
delete_transient('fvm_admin_notice_'.get_current_user_id());
|
276 |
+
|
277 |
}
|
278 |
}
|
279 |
}
|
349 |
register_activation_hook($fvm_var_file, 'fvm_plugin_activate');
|
350 |
function fvm_plugin_activate() {
|
351 |
|
352 |
+
# defauls
|
353 |
global $wpdb;
|
354 |
if(is_null($wpdb)) { return false; }
|
355 |
+
$charset_collate = $wpdb->get_charset_collate();
|
|
|
|
|
|
|
|
|
|
|
356 |
$sqla_table_name = $wpdb->prefix . 'fvm_cache';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
357 |
$sqlb_table_name = $wpdb->prefix . 'fvm_logs';
|
358 |
+
|
359 |
+
# create cache table
|
360 |
+
$sqla = "CREATE TABLE {$sqla_table_name} (
|
361 |
+
id bigint(20) unsigned NOT NULL auto_increment ,
|
362 |
+
uid varchar(64) NOT NULL,
|
363 |
+
date bigint(10) unsigned NOT NULL,
|
364 |
+
type varchar(3) NOT NULL,
|
365 |
+
content mediumtext NOT NULL,
|
366 |
+
meta mediumtext NOT NULL,
|
367 |
+
PRIMARY KEY (id),
|
368 |
+
UNIQUE KEY uid (uid),
|
369 |
+
KEY date (date), KEY type (type)
|
370 |
+
) $charset_collate;";
|
371 |
+
|
372 |
+
# create logs table
|
373 |
+
$sqlb = "CREATE TABLE {$sqlb_table_name} (
|
374 |
+
id bigint(20) unsigned NOT NULL auto_increment,
|
375 |
+
uid varchar(64) NOT NULL,
|
376 |
+
date bigint(10) unsigned NOT NULL,
|
377 |
+
type varchar(10) NOT NULL,
|
378 |
+
msg mediumtext NOT NULL,
|
379 |
+
meta mediumtext NOT NULL,
|
380 |
+
PRIMARY KEY (id),
|
381 |
+
UNIQUE KEY uid (uid),
|
382 |
+
KEY date (date),
|
383 |
+
KEY type (type)
|
384 |
+
) $charset_collate;";
|
385 |
|
386 |
# run sql
|
387 |
+
# https://developer.wordpress.org/reference/functions/dbdelta/
|
388 |
+
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
|
389 |
+
dbDelta( $sqla );
|
390 |
+
dbDelta( $sqlb );
|
391 |
+
|
392 |
+
# test if at least one table exists
|
393 |
+
if (!$wpdb->get_var($wpdb->prepare("SHOW TABLES LIKE %s", $sqla_table_name)) === $sqla_table_name) {
|
394 |
+
|
395 |
+
# log
|
396 |
+
$err = 'An error occurred when trying to create the database tables';
|
397 |
+
error_log($err);
|
398 |
+
|
399 |
+
# alert
|
400 |
+
if(is_admin()) {
|
401 |
+
$notices = array($err);
|
402 |
+
set_transient('fvm_admin_notice_'.get_current_user_id(), json_encode($notices), 10);
|
403 |
+
}
|
404 |
+
|
405 |
+
# try again in 1 hour
|
406 |
+
set_transient('fvm_table_checker', true, HOUR_IN_SECONDS);
|
407 |
+
|
408 |
+
} else {
|
409 |
+
# success, but check again tomorrow
|
410 |
+
set_transient('fvm_table_checker', true, DAY_IN_SECONDS);
|
411 |
+
}
|
412 |
|
413 |
}
|
414 |
|
416 |
# run during deactivation
|
417 |
register_deactivation_hook($fvm_var_file, 'fvm_plugin_deactivate');
|
418 |
function fvm_plugin_deactivate() {
|
419 |
+
|
420 |
+
# process cache settings
|
421 |
+
fvm_purge_static_files();
|
422 |
|
423 |
global $wpdb;
|
424 |
if(is_null($wpdb)) { return false; }
|
426 |
# remove options and tables
|
427 |
$wpdb->query("DELETE FROM {$wpdb->prefix}options WHERE option_name = 'fvm_last_cache_update'");
|
428 |
$wpdb->query("DROP TABLE IF EXISTS {$wpdb->prefix}fvm_cache");
|
429 |
+
$wpdb->query("DROP TABLE IF EXISTS {$wpdb->prefix}fvm_logs");
|
|
|
|
|
|
|
430 |
|
431 |
}
|
432 |
|
433 |
# run during uninstall
|
434 |
register_uninstall_hook($fvm_var_file, 'fvm_plugin_uninstall');
|
435 |
function fvm_plugin_uninstall() {
|
436 |
+
|
437 |
+
# process cache settings
|
438 |
+
fvm_purge_static_files();
|
439 |
+
|
440 |
global $wpdb;
|
441 |
if(is_null($wpdb)) { return false; }
|
442 |
|
446 |
$wpdb->query("DROP TABLE IF EXISTS {$wpdb->prefix}fvm_cache");
|
447 |
$wpdb->query("DROP TABLE IF EXISTS {$wpdb->prefix}fvm_logs");
|
448 |
|
|
|
|
|
|
|
449 |
}
|
450 |
|
451 |
|
inc/common.php
CHANGED
@@ -214,7 +214,7 @@ function fvm_purge_others(){
|
|
214 |
do_action("swcfpc_purge_everything");
|
215 |
return __( 'All caches on <strong>WP Cloudflare Super Page Cache</strong> have been purged.', 'fast-velocity-minify' );
|
216 |
}
|
217 |
-
|
218 |
# Purge Hyper Cache
|
219 |
if (class_exists( 'HyperCache' )) {
|
220 |
do_action( 'autoptimize_action_cachepurged' );
|
@@ -255,6 +255,30 @@ function fvm_purge_others(){
|
|
255 |
do_action('wpo_cache_flush');
|
256 |
return __( 'All caches on <strong>WP-Optimize</strong> have been purged.', 'fast-velocity-minify' );
|
257 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
258 |
|
259 |
# hosting companies
|
260 |
|
@@ -316,15 +340,59 @@ function fvm_purge_others(){
|
|
316 |
if(function_exists('pantheon_wp_clear_edge_all')) {
|
317 |
pantheon_wp_clear_edge_all();
|
318 |
}
|
|
|
|
|
|
|
|
|
|
|
319 |
|
320 |
-
#
|
321 |
-
if
|
322 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
323 |
}
|
324 |
|
325 |
}
|
326 |
|
327 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
328 |
# Purge Godaddy Managed WordPress Hosting (Varnish)
|
329 |
function fvm_godaddy_request( $method) {
|
330 |
$url = home_url();
|
@@ -456,24 +524,41 @@ function fvm_generate_min_url($url, $tkey, $type, $code) {
|
|
456 |
if(isset($ch_info['ch_url']) && !empty($ch_info['ch_url']) && isset($ch_info['ch_dir']) && !empty($ch_info['ch_dir'])) {
|
457 |
if(is_dir($ch_info['ch_dir']) && is_writable($ch_info['ch_dir'])) {
|
458 |
|
459 |
-
#
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
473 |
}
|
474 |
-
|
475 |
-
# return url
|
476 |
-
return $public;
|
477 |
|
478 |
}
|
479 |
}
|
@@ -549,34 +634,51 @@ function fvm_purge_static_files() {
|
|
549 |
if(isset($ch_info['ch_url']) && !empty($ch_info['ch_url']) && isset($ch_info['ch_dir']) && !empty($ch_info['ch_dir'])) {
|
550 |
if(is_dir($ch_info['ch_dir']) && is_writable($ch_info['ch_dir'])) {
|
551 |
|
552 |
-
#
|
553 |
-
|
554 |
-
|
555 |
-
|
556 |
-
|
557 |
-
|
558 |
-
|
559 |
-
|
560 |
-
|
561 |
-
|
562 |
-
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
573 |
}
|
574 |
}
|
575 |
-
}
|
576 |
-
}
|
577 |
|
578 |
-
|
579 |
|
|
|
|
|
|
|
|
|
|
|
|
|
580 |
}
|
581 |
}
|
582 |
|
@@ -950,20 +1052,13 @@ function fvm_replace_css_imports($css, $rq=null) {
|
|
950 |
|
951 |
|
952 |
# remove fonts and icons from final css
|
953 |
-
function fvm_extract_fonts($css_code) {
|
954 |
|
955 |
global $fvm_settings, $fvm_urls;
|
956 |
-
$critical_fonts = array();
|
957 |
$mff = array();
|
958 |
$css_preload = array();
|
959 |
$css_code_ff = '';
|
960 |
|
961 |
-
# get list of fonts that are on the critical path and are to be left alone
|
962 |
-
if( isset($fvm_settings['css']['css_optimize_critical_fonts']) &&
|
963 |
-
!empty($fvm_settings['css']['css_optimize_critical_fonts'])) {
|
964 |
-
$critical_fonts = fvm_string_toarray($fvm_settings['css']['css_optimize_critical_fonts']);
|
965 |
-
}
|
966 |
-
|
967 |
# extract font faces
|
968 |
preg_match_all('/\@\s*font-face\s*\{([^}]+)\}/iUu', $css_code, $mff);
|
969 |
if(isset($mff[0]) && is_array($mff[0])) {
|
@@ -976,6 +1071,50 @@ function fvm_extract_fonts($css_code) {
|
|
976 |
}
|
977 |
}
|
978 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
979 |
# relative paths
|
980 |
$css_code_ff = str_replace('https://'.$fvm_urls['wp_domain'], '', $css_code_ff);
|
981 |
$css_code_ff = str_replace('http://'.$fvm_urls['wp_domain'], '', $css_code_ff);
|
@@ -999,7 +1138,7 @@ function fvm_process_cdn($html) {
|
|
999 |
# html must be an object
|
1000 |
if (!is_object($html)) {
|
1001 |
$nobj = 1;
|
1002 |
-
$html =
|
1003 |
}
|
1004 |
|
1005 |
# default integration
|
@@ -1653,32 +1792,9 @@ function fvm_can_process_common() {
|
|
1653 |
return true;
|
1654 |
}
|
1655 |
|
1656 |
-
# check if the user is logged in, and if the user role allows optimization
|
1657 |
-
function fvm_user_role_processing_allowed($group) {
|
1658 |
-
if(function_exists('is_user_logged_in') && function_exists('wp_get_current_user')) {
|
1659 |
-
if(is_user_logged_in()) {
|
1660 |
-
|
1661 |
-
# get user roles
|
1662 |
-
global $fvm_settings;
|
1663 |
-
$user = wp_get_current_user();
|
1664 |
-
$roles = (array) $user->roles;
|
1665 |
-
foreach($roles as $role) {
|
1666 |
-
if(isset($fvm_settings['minify'][$role]) && $fvm_settings['minify'][$role] == true) {
|
1667 |
-
return true;
|
1668 |
-
}
|
1669 |
-
}
|
1670 |
-
|
1671 |
-
# disable for other logged in users by default
|
1672 |
-
return false;
|
1673 |
-
}
|
1674 |
-
}
|
1675 |
-
|
1676 |
-
# allow by default
|
1677 |
-
return true;
|
1678 |
-
}
|
1679 |
|
1680 |
# check if we can process the page, minimum filters
|
1681 |
-
function fvm_can_process_query_string(
|
1682 |
|
1683 |
# host and uri path
|
1684 |
$host = fvm_get_domain();
|
@@ -1693,11 +1809,17 @@ function fvm_can_process_query_string($loc) {
|
|
1693 |
# check
|
1694 |
$qsarr = array(); parse_str($parse["query"], $qsarr);
|
1695 |
|
1696 |
-
# allowed
|
1697 |
-
if(isset($
|
1698 |
-
|
1699 |
-
|
1700 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
1701 |
if(count($qsarr) > 0) {
|
1702 |
return false;
|
1703 |
}
|
@@ -1707,6 +1829,29 @@ function fvm_can_process_query_string($loc) {
|
|
1707 |
return true;
|
1708 |
}
|
1709 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1710 |
|
1711 |
|
1712 |
# check if page is amp
|
214 |
do_action("swcfpc_purge_everything");
|
215 |
return __( 'All caches on <strong>WP Cloudflare Super Page Cache</strong> have been purged.', 'fast-velocity-minify' );
|
216 |
}
|
217 |
+
|
218 |
# Purge Hyper Cache
|
219 |
if (class_exists( 'HyperCache' )) {
|
220 |
do_action( 'autoptimize_action_cachepurged' );
|
255 |
do_action('wpo_cache_flush');
|
256 |
return __( 'All caches on <strong>WP-Optimize</strong> have been purged.', 'fast-velocity-minify' );
|
257 |
}
|
258 |
+
|
259 |
+
# nginx helper
|
260 |
+
if(has_action('rt_nginx_helper_purge_all')) {
|
261 |
+
do_action('rt_nginx_helper_purge_all');
|
262 |
+
$ret[] = __( 'Nginx Helper' );
|
263 |
+
}
|
264 |
+
|
265 |
+
|
266 |
+
# Object Cache
|
267 |
+
|
268 |
+
# WordPress OPCache
|
269 |
+
if (function_exists('wp_cache_flush')) {
|
270 |
+
wp_cache_flush();
|
271 |
+
}
|
272 |
+
|
273 |
+
# Purge Redis Object Cache plugin
|
274 |
+
if(class_exists('Redis') && defined('WP_REDIS_PATH')) {
|
275 |
+
$r = new Redis();
|
276 |
+
if ($r->connect( WP_REDIS_PATH, 0 )) {
|
277 |
+
if( false !== $r->flushdb() ) {
|
278 |
+
$ret[] = __('Redis Object Cache');
|
279 |
+
}
|
280 |
+
}
|
281 |
+
}
|
282 |
|
283 |
# hosting companies
|
284 |
|
340 |
if(function_exists('pantheon_wp_clear_edge_all')) {
|
341 |
pantheon_wp_clear_edge_all();
|
342 |
}
|
343 |
+
|
344 |
+
# cloudways varnish
|
345 |
+
if(fvm_purge_varnish_cloudways()) {
|
346 |
+
$ret[] = __('Cloudways (Varnish)');
|
347 |
+
}
|
348 |
|
349 |
+
# bigscoots.com
|
350 |
+
if(has_action('bs_cache_purge_cache')) {
|
351 |
+
do_action('bs_cache_purge_cache');
|
352 |
+
$ret[] = __( 'BigScoots' );
|
353 |
+
}
|
354 |
+
|
355 |
+
# godaddy.com managed WordPress
|
356 |
+
if (class_exists('WPass') && method_exists('WPass\Cache', 'do_ban')){
|
357 |
+
WPaaS\Cache::do_ban();
|
358 |
+
$ret[] = __( 'GoDaddy' );
|
359 |
}
|
360 |
|
361 |
}
|
362 |
|
363 |
|
364 |
+
# purge varnish on cloudways
|
365 |
+
function fvm_purge_varnish_cloudways() {
|
366 |
+
|
367 |
+
# cloudways detection
|
368 |
+
if (!isset($_SERVER['cw_allowed_ip'])){ return false; }
|
369 |
+
|
370 |
+
# must have
|
371 |
+
if (!isset($_SERVER['HTTP_X_VARNISH']) || !isset($_SERVER['HTTP_X_APPLICATION'])){ return false; }
|
372 |
+
if (is_null($_SERVER['HTTP_X_VARNISH']) || is_null($_SERVER['HTTP_X_APPLICATION'])){ return false; }
|
373 |
+
if ('varnishpass' === trim($_SERVER['HTTP_X_APPLICATION'])){ return false; }
|
374 |
+
if ('bypass' === trim($_SERVER['HTTP_X_APPLICATION'])){ return false; }
|
375 |
+
|
376 |
+
# host and uri path
|
377 |
+
$host = wpraiser_get_domain();
|
378 |
+
|
379 |
+
# request arguments
|
380 |
+
$request_args = array('method' => 'PURGE', 'redirection' => 0, 'timeout' => 10, 'blocking' => false, 'headers' => array('Host' => $host, 'X-Purge-Method' => 'regex') );
|
381 |
+
|
382 |
+
# default host and port
|
383 |
+
$varnish_ip = '127.0.0.1';
|
384 |
+
$varnish_port = '8080';
|
385 |
+
|
386 |
+
# overwrite by constant
|
387 |
+
if(defined('FVM_VARNISH_IP') && !empty(FVM_VARNISH_IP)) { $varnish_ip = trim(FVM_VARNISH_IP); }
|
388 |
+
if(defined('FVM_VARNISH_PORT') && !empty(FVM_VARNISH_PORT)) { $varnish_port = trim(FVM_VARNISH_PORT); }
|
389 |
+
|
390 |
+
# purge async
|
391 |
+
$response = wp_remote_request('http://'.$varnish_ip.':'.$varnish_port.'/.*', $request_args);
|
392 |
+
return true;
|
393 |
+
}
|
394 |
+
|
395 |
+
|
396 |
# Purge Godaddy Managed WordPress Hosting (Varnish)
|
397 |
function fvm_godaddy_request( $method) {
|
398 |
$url = home_url();
|
524 |
if(isset($ch_info['ch_url']) && !empty($ch_info['ch_url']) && isset($ch_info['ch_dir']) && !empty($ch_info['ch_dir'])) {
|
525 |
if(is_dir($ch_info['ch_dir']) && is_writable($ch_info['ch_dir'])) {
|
526 |
|
527 |
+
# get file system type
|
528 |
+
if(function_exists('get_filesystem_method')) {
|
529 |
+
$access_type = get_filesystem_method();
|
530 |
+
if($access_type === 'direct') {
|
531 |
+
|
532 |
+
# get credentials
|
533 |
+
$creds = request_filesystem_credentials(site_url() . '/wp-admin/', '', false, false, array());
|
534 |
+
|
535 |
+
/* initialize the API */
|
536 |
+
if ( ! WP_Filesystem($creds) ) {
|
537 |
+
error_log('FVM could not find the WP filesystem.');
|
538 |
+
return false;
|
539 |
+
}
|
540 |
+
|
541 |
+
global $wp_filesystem;
|
542 |
+
/* do our file manipulations below */
|
543 |
+
|
544 |
+
# filename
|
545 |
+
$file = $ch_info['ch_dir'] . DIRECTORY_SEPARATOR . $filename;
|
546 |
+
$public = $ch_info['ch_url'] . '/' .$filename;
|
547 |
+
|
548 |
+
# create if doesn't exist
|
549 |
+
if(!$wp_filesystem->exists($file) || ($wp_filesystem->exists($file) && $wp_filesystem->mtime($file) < $tvers)) {
|
550 |
+
$wp_filesystem->put_contents($file, $code);
|
551 |
+
}
|
552 |
+
|
553 |
+
# return url
|
554 |
+
return $public;
|
555 |
+
|
556 |
+
|
557 |
+
} else {
|
558 |
+
/* don't have direct write access. Prompt user with our notice */
|
559 |
+
error_log('FVM has no direct write access for CSS / JS cache files.');
|
560 |
+
}
|
561 |
}
|
|
|
|
|
|
|
562 |
|
563 |
}
|
564 |
}
|
634 |
if(isset($ch_info['ch_url']) && !empty($ch_info['ch_url']) && isset($ch_info['ch_dir']) && !empty($ch_info['ch_dir'])) {
|
635 |
if(is_dir($ch_info['ch_dir']) && is_writable($ch_info['ch_dir'])) {
|
636 |
|
637 |
+
# get file system type
|
638 |
+
if(function_exists('get_filesystem_method')) {
|
639 |
+
$access_type = get_filesystem_method();
|
640 |
+
if($access_type === 'direct') {
|
641 |
+
|
642 |
+
# get credentials
|
643 |
+
$creds = request_filesystem_credentials(site_url() . '/wp-admin/', '', false, false, array());
|
644 |
+
|
645 |
+
/* initialize the API */
|
646 |
+
if ( ! WP_Filesystem($creds) ) {
|
647 |
+
error_log('FVM could not find the WP filesystem.');
|
648 |
+
return false;
|
649 |
+
}
|
650 |
+
|
651 |
+
global $wp_filesystem;
|
652 |
+
/* do our file manipulations below */
|
653 |
+
|
654 |
+
# instant purge
|
655 |
+
if(isset($fvm_settings['cache']['min_instant_purge']) && $fvm_settings['cache']['min_instant_purge'] == true) {
|
656 |
+
$wp_filesystem->rmdir($ch_info['ch_dir'], true);
|
657 |
+
error_log('FVM instant cache purge.');
|
658 |
+
return true;
|
659 |
+
} else {
|
660 |
+
|
661 |
+
# older than 7 days and not matching current timestamp
|
662 |
+
error_log('FVM cache purge for files older than 7 days ago.');
|
663 |
+
$list = $wp_filesystem->dirlist($ch_info['ch_dir'], false, true);
|
664 |
+
if(is_array($list) && count($list) > 0) {
|
665 |
+
foreach($list as $k=>$arr) {
|
666 |
+
if(isset($arr['lastmodunix']) && $arr['type'] == 'f' && intval($arr['lastmodunix']) <= time()-86400*7) {
|
667 |
+
if(substr($arr['name'], 0, 10) !== time()) {
|
668 |
+
$wp_filesystem->delete($ch_info['ch_dir'] . DIRECTORY_SEPARATOR . $arr['name'], false, 'f');
|
669 |
+
}
|
670 |
+
}
|
671 |
}
|
672 |
}
|
|
|
|
|
673 |
|
674 |
+
}
|
675 |
|
676 |
+
} else {
|
677 |
+
/* don't have direct write access. Prompt user with our notice */
|
678 |
+
error_log('FVM has no direct write access for CSS / JS cache files.');
|
679 |
+
}
|
680 |
+
}
|
681 |
+
|
682 |
}
|
683 |
}
|
684 |
|
1052 |
|
1053 |
|
1054 |
# remove fonts and icons from final css
|
1055 |
+
function fvm_extract_fonts($css_code, $url=null) {
|
1056 |
|
1057 |
global $fvm_settings, $fvm_urls;
|
|
|
1058 |
$mff = array();
|
1059 |
$css_preload = array();
|
1060 |
$css_code_ff = '';
|
1061 |
|
|
|
|
|
|
|
|
|
|
|
|
|
1062 |
# extract font faces
|
1063 |
preg_match_all('/\@\s*font-face\s*\{([^}]+)\}/iUu', $css_code, $mff);
|
1064 |
if(isset($mff[0]) && is_array($mff[0])) {
|
1071 |
}
|
1072 |
}
|
1073 |
|
1074 |
+
# add font-display swap for all font faces
|
1075 |
+
# https://developers.google.com/web/updates/2016/02/font-display
|
1076 |
+
$css_code_ff = preg_replace_callback('/(?:@font-face)\s*{(?<value>[^}]+)}/i',
|
1077 |
+
function ($matches) {
|
1078 |
+
if(stripos($matches['value'], 'font-display') !== false) {
|
1079 |
+
return $matches[0];
|
1080 |
+
} else {
|
1081 |
+
return str_replace($matches['value'], 'font-display:swap;'.$matches['value'], $matches[0] );
|
1082 |
+
}
|
1083 |
+
},
|
1084 |
+
$css_code_ff
|
1085 |
+
);
|
1086 |
+
|
1087 |
+
# add font-display swap for all font faces
|
1088 |
+
# https://developers.google.com/web/updates/2016/02/font-display
|
1089 |
+
$css_code = preg_replace_callback('/(?:@font-face)\s*{(?<value>[^}]+)}/i',
|
1090 |
+
function ($matches) {
|
1091 |
+
if(stripos($matches['value'], 'font-display') !== false) {
|
1092 |
+
return $matches[0];
|
1093 |
+
} else {
|
1094 |
+
return str_replace($matches['value'], 'font-display:swap;'.$matches['value'], $matches[0] );
|
1095 |
+
}
|
1096 |
+
},
|
1097 |
+
$css_code
|
1098 |
+
);
|
1099 |
+
|
1100 |
+
# remove query strings from fonts
|
1101 |
+
$css_code_ff = preg_replace('/(.eot|.woff2|.woff|.ttf)+[?+](.+?)(\)|\'|\")/ui', "$1"."$3", $css_code_ff);
|
1102 |
+
$css_code = preg_replace('/(.eot|.woff2|.woff|.ttf)+[?+](.+?)(\)|\'|\")/ui', "$1"."$3", $css_code);
|
1103 |
+
|
1104 |
+
# fix url paths css_code_ff
|
1105 |
+
if(!empty($url)) {
|
1106 |
+
$matches = array(); preg_match_all("/url\(\s*['\"]?(?!data:)(?!http)(?![\/'\"])(.+?)['\"]?\s*\)/ui", $css_code_ff, $matches);
|
1107 |
+
foreach($matches[1] as $a) { $b = trim($a); if($b != $a) { $css_code_ff = str_replace($a, $b, $css_code_ff); } }
|
1108 |
+
$css_code_ff = preg_replace("/url\(\s*['\"]?(?!data:)(?!http)(?![\/'\"#])(.+?)['\"]?\s*\)/ui", "url(".dirname($url)."/$1)", $css_code_ff);
|
1109 |
+
}
|
1110 |
+
|
1111 |
+
# fix url paths css_code
|
1112 |
+
if(!empty($url)) {
|
1113 |
+
$matches = array(); preg_match_all("/url\(\s*['\"]?(?!data:)(?!http)(?![\/'\"])(.+?)['\"]?\s*\)/ui", $css_code, $matches);
|
1114 |
+
foreach($matches[1] as $a) { $b = trim($a); if($b != $a) { $css_code = str_replace($a, $b, $css_code); } }
|
1115 |
+
$css_code = preg_replace("/url\(\s*['\"]?(?!data:)(?!http)(?![\/'\"#])(.+?)['\"]?\s*\)/ui", "url(".dirname($url)."/$1)", $css_code);
|
1116 |
+
}
|
1117 |
+
|
1118 |
# relative paths
|
1119 |
$css_code_ff = str_replace('https://'.$fvm_urls['wp_domain'], '', $css_code_ff);
|
1120 |
$css_code_ff = str_replace('http://'.$fvm_urls['wp_domain'], '', $css_code_ff);
|
1138 |
# html must be an object
|
1139 |
if (!is_object($html)) {
|
1140 |
$nobj = 1;
|
1141 |
+
$html = fvm_str_get_html($html, true, true, 'UTF-8', false, PHP_EOL, ' ');
|
1142 |
}
|
1143 |
|
1144 |
# default integration
|
1792 |
return true;
|
1793 |
}
|
1794 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1795 |
|
1796 |
# check if we can process the page, minimum filters
|
1797 |
+
function fvm_can_process_query_string() {
|
1798 |
|
1799 |
# host and uri path
|
1800 |
$host = fvm_get_domain();
|
1809 |
# check
|
1810 |
$qsarr = array(); parse_str($parse["query"], $qsarr);
|
1811 |
|
1812 |
+
# remove allowed query strings from the list of detected queries
|
1813 |
+
if(isset($fvm_settings['settings']['qs']) && !empty($fvm_settings['settings']['qs'])) {
|
1814 |
+
$arr = fvm_string_toarray($fvm_settings['settings']['qs']);
|
1815 |
+
if(is_array($arr) && count($arr) > 0) {
|
1816 |
+
foreach ($arr as $a) {
|
1817 |
+
if(isset($qsarr[$e])) { unset($qsarr[$e]); }
|
1818 |
+
}
|
1819 |
+
}
|
1820 |
+
}
|
1821 |
+
|
1822 |
+
# if there are other queries left, bypass processing
|
1823 |
if(count($qsarr) > 0) {
|
1824 |
return false;
|
1825 |
}
|
1829 |
return true;
|
1830 |
}
|
1831 |
|
1832 |
+
# check if the user is logged in, and if the user role allows optimization
|
1833 |
+
function fvm_user_role_processing_allowed($group) {
|
1834 |
+
if(function_exists('is_user_logged_in') && function_exists('wp_get_current_user')) {
|
1835 |
+
if(is_user_logged_in()) {
|
1836 |
+
|
1837 |
+
# get user roles
|
1838 |
+
global $fvm_settings;
|
1839 |
+
$user = wp_get_current_user();
|
1840 |
+
$roles = (array) $user->roles;
|
1841 |
+
foreach($roles as $role) {
|
1842 |
+
if(isset($fvm_settings['minify'][$role]) && $fvm_settings['minify'][$role] == true) {
|
1843 |
+
return true;
|
1844 |
+
}
|
1845 |
+
}
|
1846 |
+
|
1847 |
+
# disable for other logged in users by default
|
1848 |
+
return false;
|
1849 |
+
}
|
1850 |
+
}
|
1851 |
+
|
1852 |
+
# allow by default
|
1853 |
+
return true;
|
1854 |
+
}
|
1855 |
|
1856 |
|
1857 |
# check if page is amp
|
inc/frontend.php
CHANGED
@@ -47,7 +47,7 @@ function fvm_process_page($html) {
|
|
47 |
|
48 |
# get html into an object
|
49 |
# https://simplehtmldom.sourceforge.io/manual.htm
|
50 |
-
$html_object =
|
51 |
|
52 |
# return early if html is not an object, or overwrite html into an object for processing
|
53 |
if (!is_object($html_object)) {
|
@@ -188,7 +188,7 @@ function fvm_process_page($html) {
|
|
188 |
|
189 |
# extract fonts and icons
|
190 |
if(isset($fvm_settings['css']['fonts']) && $fvm_settings['css']['fonts'] == true) {
|
191 |
-
$extract_fonts_arr = fvm_extract_fonts($css['code']);
|
192 |
$css_lowpriority_code.= '/* '.$href.' */'. PHP_EOL . $extract_fonts_arr['fonts'];
|
193 |
$css_code = $extract_fonts_arr['code'];
|
194 |
} else {
|
@@ -259,7 +259,7 @@ function fvm_process_page($html) {
|
|
259 |
|
260 |
# extract fonts and icons
|
261 |
if(isset($fvm_settings['css']['fonts']) && $fvm_settings['css']['fonts'] == true) {
|
262 |
-
$extract_fonts_arr = fvm_extract_fonts($css['code']);
|
263 |
$css_lowpriority_code.= '/* '.$href.' */'. PHP_EOL . $extract_fonts_arr['fonts'];
|
264 |
$css_code = $extract_fonts_arr['code'];
|
265 |
} else {
|
47 |
|
48 |
# get html into an object
|
49 |
# https://simplehtmldom.sourceforge.io/manual.htm
|
50 |
+
$html_object = fvm_str_get_html($html, false, true, 'UTF-8', false, PHP_EOL, ' ');
|
51 |
|
52 |
# return early if html is not an object, or overwrite html into an object for processing
|
53 |
if (!is_object($html_object)) {
|
188 |
|
189 |
# extract fonts and icons
|
190 |
if(isset($fvm_settings['css']['fonts']) && $fvm_settings['css']['fonts'] == true) {
|
191 |
+
$extract_fonts_arr = fvm_extract_fonts($css['code'], $href);
|
192 |
$css_lowpriority_code.= '/* '.$href.' */'. PHP_EOL . $extract_fonts_arr['fonts'];
|
193 |
$css_code = $extract_fonts_arr['code'];
|
194 |
} else {
|
259 |
|
260 |
# extract fonts and icons
|
261 |
if(isset($fvm_settings['css']['fonts']) && $fvm_settings['css']['fonts'] == true) {
|
262 |
+
$extract_fonts_arr = fvm_extract_fonts($css['code'], $href);
|
263 |
$css_lowpriority_code.= '/* '.$href.' */'. PHP_EOL . $extract_fonts_arr['fonts'];
|
264 |
$css_code = $extract_fonts_arr['code'];
|
265 |
} else {
|
layout/admin-layout-help.php
CHANGED
@@ -285,6 +285,21 @@
|
|
285 |
</div>
|
286 |
</div>
|
287 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
288 |
<div style="height: 20px;"></div>
|
289 |
<h2 class="title">User Settings</h2>
|
290 |
|
285 |
</div>
|
286 |
</div>
|
287 |
|
288 |
+
<div style="height: 20px;"></div>
|
289 |
+
<h2 class="title">Query String Settings</h2>
|
290 |
+
|
291 |
+
<div class="accordion">
|
292 |
+
<h3>Allowed Query Strings</h3>
|
293 |
+
<div>
|
294 |
+
<p><strong>Notes:</strong></p>
|
295 |
+
<p>This allows processing of CSS, HTML and JS when the url contains certain query strings, but note that if there are other query strings found on the same url not on the list of allowed query strings, it will still not process the url.</p>
|
296 |
+
<p><strong>Example Settings:</strong></p>
|
297 |
+
<p class="fvm-code-full">
|
298 |
+
utm_source<br />utm_campaign<br />utm_medium<br />utm_expid<br />utm_term<br />utm_content<br />fb_action_ids<br />fb_action_types<br />fb_source<br />fbclid<br />_ga<br />gclid<br />age-verified<br />usqp<br />cn-reloaded<br />lang<br />s<br />permalink_name<br />lp-variation-id<br />author<br />author_name<br />cat<br />category_name<br />order<br />orderby<br />p<br />page_id<br />page<br />paged<br />post_type<br />posts<br />s<br />search<br />taxonomy<br />tag<br />tag_id<br />term
|
299 |
+
</p>
|
300 |
+
</div>
|
301 |
+
</div>
|
302 |
+
|
303 |
<div style="height: 20px;"></div>
|
304 |
<h2 class="title">User Settings</h2>
|
305 |
|
layout/admin-layout-settings.php
CHANGED
@@ -22,7 +22,7 @@
|
|
22 |
<fieldset>
|
23 |
<label for="fvm_settings_cache_min_instant_purge">
|
24 |
<input name="fvm_settings[cache][min_instant_purge]" type="checkbox" id="fvm_settings_cache_min_instant_purge" value="1" <?php echo fvm_get_settings_checkbox(fvm_get_settings_value($fvm_settings, 'cache', 'min_instant_purge')); ?>>
|
25 |
-
<?php _e( 'Purge Minified CSS/JS files instantly', 'fast-velocity-minify' ); ?> <span class="note-info">[ <?php _e( '
|
26 |
<br />
|
27 |
|
28 |
</fieldset></td>
|
@@ -160,7 +160,7 @@
|
|
160 |
<td><fieldset>
|
161 |
<label for="fvm_settings_css_remove"><span class="fvm-bold-green fvm-rowintro"><?php _e( 'Remove the following CSS files', 'fast-velocity-minify' ); ?></span></label>
|
162 |
<p><textarea name="fvm_settings[css][remove]" rows="7" cols="50" id="fvm_settings_css_remove" class="large-text code" placeholder="ex: fonts.googleapis.com"><?php echo fvm_get_settings_value($fvm_settings, 'css', 'remove'); ?></textarea></p>
|
163 |
-
<p class="description">[ <?php _e( 'This will allow you to remove unwanted CSS files by
|
164 |
<p class="description">[ <?php _e( 'Will match using <code>PHP stripos</code> against the <code>href attribute</code> on the <code>link tag</code>', 'fast-velocity-minify' ); ?> ]</p>
|
165 |
</fieldset></td>
|
166 |
</tr>
|
@@ -170,7 +170,7 @@
|
|
170 |
<td><fieldset>
|
171 |
<label for="fvm_settings_css_async"><span class="fvm-bold-green fvm-rowintro"><?php _e( 'Async the following CSS files', 'fast-velocity-minify' ); ?></span></label>
|
172 |
<p><textarea name="fvm_settings[css][async]" rows="7" cols="50" id="fvm_settings_css_async" class="large-text code" placeholder="ex: /plugins/something/assets/low-priority.css"><?php echo fvm_get_settings_value($fvm_settings, 'css', 'async'); ?></textarea></p>
|
173 |
-
<p class="description">[ <?php _e( 'This will allow you to
|
174 |
<p class="description">[ <?php _e( 'Will match using <code>PHP stripos</code> against the <code>href attribute</code> on the <code>link tag</code>', 'fast-velocity-minify' ); ?> ]</p>
|
175 |
</fieldset></td>
|
176 |
</tr>
|
@@ -363,6 +363,22 @@ www.googletagmanager.com/gtm.js"><?php echo fvm_get_settings_value($fvm_settings
|
|
363 |
</tbody></table>
|
364 |
|
365 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
366 |
<div style="height: 60px;"></div>
|
367 |
<h2 class="title"><?php _e( 'User Settings', 'fast-velocity-minify' ); ?></h2>
|
368 |
<h3 class="fvm-bold-green"><?php _e( 'For compatibility reasons, only anonymous users should be optimized by default.', 'fast-velocity-minify' ); ?></h3>
|
22 |
<fieldset>
|
23 |
<label for="fvm_settings_cache_min_instant_purge">
|
24 |
<input name="fvm_settings[cache][min_instant_purge]" type="checkbox" id="fvm_settings_cache_min_instant_purge" value="1" <?php echo fvm_get_settings_checkbox(fvm_get_settings_value($fvm_settings, 'cache', 'min_instant_purge')); ?>>
|
25 |
+
<?php _e( 'Purge Minified CSS/JS files instantly', 'fast-velocity-minify' ); ?> <span class="note-info">[ <?php _e( 'CSS & JS cache files are preserved for 7 days by default, for better compatibility with certain hosting providers.', 'fast-velocity-minify' ); ?> ]</span></label>
|
26 |
<br />
|
27 |
|
28 |
</fieldset></td>
|
160 |
<td><fieldset>
|
161 |
<label for="fvm_settings_css_remove"><span class="fvm-bold-green fvm-rowintro"><?php _e( 'Remove the following CSS files', 'fast-velocity-minify' ); ?></span></label>
|
162 |
<p><textarea name="fvm_settings[css][remove]" rows="7" cols="50" id="fvm_settings_css_remove" class="large-text code" placeholder="ex: fonts.googleapis.com"><?php echo fvm_get_settings_value($fvm_settings, 'css', 'remove'); ?></textarea></p>
|
163 |
+
<p class="description">[ <?php _e( 'This will allow you to remove unwanted CSS files by URI path from the frontend', 'fast-velocity-minify' ); ?> ]</p>
|
164 |
<p class="description">[ <?php _e( 'Will match using <code>PHP stripos</code> against the <code>href attribute</code> on the <code>link tag</code>', 'fast-velocity-minify' ); ?> ]</p>
|
165 |
</fieldset></td>
|
166 |
</tr>
|
170 |
<td><fieldset>
|
171 |
<label for="fvm_settings_css_async"><span class="fvm-bold-green fvm-rowintro"><?php _e( 'Async the following CSS files', 'fast-velocity-minify' ); ?></span></label>
|
172 |
<p><textarea name="fvm_settings[css][async]" rows="7" cols="50" id="fvm_settings_css_async" class="large-text code" placeholder="ex: /plugins/something/assets/low-priority.css"><?php echo fvm_get_settings_value($fvm_settings, 'css', 'async'); ?></textarea></p>
|
173 |
+
<p class="description">[ <?php _e( 'This will allow you to Async CSS files by URI path from the frontend', 'fast-velocity-minify' ); ?> ]</p>
|
174 |
<p class="description">[ <?php _e( 'Will match using <code>PHP stripos</code> against the <code>href attribute</code> on the <code>link tag</code>', 'fast-velocity-minify' ); ?> ]</p>
|
175 |
</fieldset></td>
|
176 |
</tr>
|
363 |
</tbody></table>
|
364 |
|
365 |
|
366 |
+
<div style="height: 60px;"></div>
|
367 |
+
<h2 class="title"><?php _e( 'Query Strings', 'fast-velocity-minify' ); ?></h2>
|
368 |
+
<h3 class="fvm-bold-green"><?php _e( 'Allow processing of CSS, JS & HTML on specific query strings', 'fast-velocity-minify' ); ?></h3>
|
369 |
+
<table class="form-table fvm-settings">
|
370 |
+
<tbody>
|
371 |
+
<tr>
|
372 |
+
<th scope="row"><?php _e( 'Allowed Query Strings', 'fast-velocity-minify' ); ?></th>
|
373 |
+
<td><fieldset>
|
374 |
+
<label for="fvm_settings_settings_qs"><span class="fvm-bold-green fvm-rowintro"><?php _e( 'One query string key per line', 'fast-velocity-minify' ); ?></span></label>
|
375 |
+
<p><textarea name="fvm_settings[settings][qs]" rows="7" cols="50" id="fvm_settings_settings_qs" class="large-text code" placeholder="--- check the help section for suggestions ---"><?php echo fvm_get_settings_value($fvm_settings, 'settings', 'qs'); ?></textarea></p>
|
376 |
+
<p class="description">[ <?php _e( 'Additional query strings, keys only', 'fast-velocity-minify' ); ?> ]</p>
|
377 |
+
</fieldset></td>
|
378 |
+
</tr>
|
379 |
+
</tbody></table>
|
380 |
+
|
381 |
+
|
382 |
<div style="height: 60px;"></div>
|
383 |
<h2 class="title"><?php _e( 'User Settings', 'fast-velocity-minify' ); ?></h2>
|
384 |
<h3 class="fvm-bold-green"><?php _e( 'For compatibility reasons, only anonymous users should be optimized by default.', 'fast-velocity-minify' ); ?></h3>
|
libs/matthiasmullie/minify/src/CSS.php
CHANGED
@@ -563,47 +563,7 @@ class CSS extends Minify
|
|
563 |
*/
|
564 |
protected function shortenZeroes($content)
|
565 |
{
|
566 |
-
//
|
567 |
-
// `5px - 0px` is valid, but `5px - 0` is not
|
568 |
-
// `10px * 0` is valid (equates to 0), and so is `10 * 0px`, but
|
569 |
-
// `10 * 0` is invalid
|
570 |
-
// we've extracted calcs earlier, so we don't need to worry about this
|
571 |
-
|
572 |
-
// reusable bits of code throughout these regexes:
|
573 |
-
// before & after are used to make sure we don't match lose unintended
|
574 |
-
// 0-like values (e.g. in #000, or in http://url/1.0)
|
575 |
-
// units can be stripped from 0 values, or used to recognize non 0
|
576 |
-
// values (where wa may be able to strip a .0 suffix)
|
577 |
-
$before = '(?<=[:(, ])';
|
578 |
-
$after = '(?=[ ,);}])';
|
579 |
-
$units = '(em|ex|%|px|cm|mm|in|pt|pc|ch|rem|vh|vw|vmin|vmax|vm)';
|
580 |
-
|
581 |
-
// strip units after zeroes (0px -> 0)
|
582 |
-
// NOTE: it should be safe to remove all units for a 0 value, but in
|
583 |
-
// practice, Webkit (especially Safari) seems to stumble over at least
|
584 |
-
// 0%, potentially other units as well. Only stripping 'px' for now.
|
585 |
-
// @see https://github.com/matthiasmullie/minify/issues/60
|
586 |
-
$content = preg_replace('/'.$before.'(-?0*(\.0+)?)(?<=0)px'.$after.'/', '\\1', $content);
|
587 |
-
|
588 |
-
// strip 0-digits (.0 -> 0)
|
589 |
-
$content = preg_replace('/'.$before.'\.0+'.$units.'?'.$after.'/', '0\\1', $content);
|
590 |
-
// strip trailing 0: 50.10 -> 50.1, 50.10px -> 50.1px
|
591 |
-
$content = preg_replace('/'.$before.'(-?[0-9]+\.[0-9]+)0+'.$units.'?'.$after.'/', '\\1\\2', $content);
|
592 |
-
// strip trailing 0: 50.00 -> 50, 50.00px -> 50px
|
593 |
-
$content = preg_replace('/'.$before.'(-?[0-9]+)\.0+'.$units.'?'.$after.'/', '\\1\\2', $content);
|
594 |
-
// strip leading 0: 0.1 -> .1, 01.1 -> 1.1
|
595 |
-
$content = preg_replace('/'.$before.'(-?)0+([0-9]*\.[0-9]+)'.$units.'?'.$after.'/', '\\1\\2\\3', $content);
|
596 |
-
|
597 |
-
// strip negative zeroes (-0 -> 0) & truncate zeroes (00 -> 0)
|
598 |
-
$content = preg_replace('/'.$before.'-?0+'.$units.'?'.$after.'/', '0\\1', $content);
|
599 |
-
|
600 |
-
// IE doesn't seem to understand a unitless flex-basis value (correct -
|
601 |
-
// it goes against the spec), so let's add it in again (make it `%`,
|
602 |
-
// which is only 1 char: 0%, 0px, 0 anything, it's all just the same)
|
603 |
-
// @see https://developer.mozilla.org/nl/docs/Web/CSS/flex
|
604 |
-
$content = preg_replace('/flex:([0-9]+\s[0-9]+\s)0([;\}])/', 'flex:${1}0%${2}', $content);
|
605 |
-
$content = preg_replace('/flex-basis:0([;\}])/', 'flex-basis:0%${1}', $content);
|
606 |
-
|
607 |
return $content;
|
608 |
}
|
609 |
|
563 |
*/
|
564 |
protected function shortenZeroes($content)
|
565 |
{
|
566 |
+
// removed
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
567 |
return $content;
|
568 |
}
|
569 |
|
libs/simplehtmldom/simple_html_dom.php
CHANGED
@@ -26,32 +26,32 @@ if (!defined('ABSPATH')){ exit(); }
|
|
26 |
|
27 |
# mod
|
28 |
defined('FVM_MAX_FILE_SIZE') || define('FVM_MAX_FILE_SIZE', 2000000); # Process HTML up to 2 Mb
|
29 |
-
defined('
|
30 |
-
defined('
|
31 |
-
defined('
|
32 |
|
33 |
# other
|
34 |
-
define('
|
35 |
-
define('
|
36 |
-
define('
|
37 |
-
define('
|
38 |
-
define('
|
39 |
-
define('
|
40 |
-
define('
|
41 |
-
define('
|
42 |
-
define('
|
43 |
-
define('
|
44 |
-
define('
|
45 |
-
define('
|
46 |
-
define('
|
47 |
-
define('
|
48 |
-
define('
|
49 |
-
define('
|
50 |
-
define('
|
51 |
-
define('
|
52 |
|
53 |
# functions
|
54 |
-
function
|
55 |
$url,
|
56 |
$use_include_path = false,
|
57 |
$context = null,
|
@@ -59,10 +59,10 @@ function file_get_html(
|
|
59 |
$maxLen = -1,
|
60 |
$lowercase = true,
|
61 |
$forceTagsClosed = true,
|
62 |
-
$target_charset =
|
63 |
$stripRN = true,
|
64 |
-
$defaultBRText =
|
65 |
-
$defaultSpanText =
|
66 |
{
|
67 |
if($maxLen <= 0) { $maxLen = FVM_MAX_FILE_SIZE; }
|
68 |
|
@@ -97,14 +97,14 @@ function file_get_html(
|
|
97 |
return $dom->load($contents, $lowercase, $stripRN);
|
98 |
}
|
99 |
|
100 |
-
function
|
101 |
$str,
|
102 |
$lowercase = true,
|
103 |
$forceTagsClosed = true,
|
104 |
-
$target_charset =
|
105 |
$stripRN = true,
|
106 |
-
$defaultBRText =
|
107 |
-
$defaultSpanText =
|
108 |
{
|
109 |
$dom = new simple_html_dom(
|
110 |
null,
|
@@ -124,14 +124,14 @@ function str_get_html(
|
|
124 |
return $dom->load($str, $lowercase, $stripRN);
|
125 |
}
|
126 |
|
127 |
-
function
|
128 |
{
|
129 |
$node->dump($node);
|
130 |
}
|
131 |
|
132 |
-
class
|
133 |
{
|
134 |
-
public $nodetype =
|
135 |
public $tag = 'text';
|
136 |
public $attr = array();
|
137 |
public $children = array();
|
@@ -218,10 +218,10 @@ class simple_html_dom_node
|
|
218 |
$string .= " text: ({$this->text})";
|
219 |
}
|
220 |
|
221 |
-
$string .= '
|
222 |
|
223 |
-
if (isset($node->_[
|
224 |
-
$string .= "'" . $node->_[
|
225 |
} else {
|
226 |
$string .= ' NULL ';
|
227 |
}
|
@@ -345,12 +345,12 @@ class simple_html_dom_node
|
|
345 |
|
346 |
function innertext()
|
347 |
{
|
348 |
-
if (isset($this->_[
|
349 |
-
return $this->_[
|
350 |
}
|
351 |
|
352 |
-
if (isset($this->_[
|
353 |
-
return $this->dom->restore_noise($this->_[
|
354 |
}
|
355 |
|
356 |
$ret = '';
|
@@ -387,24 +387,24 @@ class simple_html_dom_node
|
|
387 |
call_user_func_array($this->dom->callback, array($this));
|
388 |
}
|
389 |
|
390 |
-
if (isset($this->_[
|
391 |
-
return $this->_[
|
392 |
}
|
393 |
|
394 |
-
if (isset($this->_[
|
395 |
-
return $this->dom->restore_noise($this->_[
|
396 |
}
|
397 |
|
398 |
$ret = '';
|
399 |
|
400 |
-
if ($this->dom && $this->dom->nodes[$this->_[
|
401 |
-
$ret = $this->dom->nodes[$this->_[
|
402 |
}
|
403 |
|
404 |
-
if (isset($this->_[
|
405 |
-
// todo: <br> should either never have
|
406 |
if ($this->tag !== 'br') {
|
407 |
-
$ret .= $this->_[
|
408 |
}
|
409 |
} elseif ($this->nodes) {
|
410 |
foreach ($this->nodes as $n) {
|
@@ -412,7 +412,7 @@ class simple_html_dom_node
|
|
412 |
}
|
413 |
}
|
414 |
|
415 |
-
if (isset($this->_[
|
416 |
$ret .= '</' . $this->tag . '>';
|
417 |
}
|
418 |
|
@@ -421,14 +421,14 @@ class simple_html_dom_node
|
|
421 |
|
422 |
function text()
|
423 |
{
|
424 |
-
if (isset($this->_[
|
425 |
-
return $this->_[
|
426 |
}
|
427 |
|
428 |
switch ($this->nodetype) {
|
429 |
-
case
|
430 |
-
case
|
431 |
-
case
|
432 |
}
|
433 |
|
434 |
if (strcasecmp($this->tag, 'script') === 0) { return ''; }
|
@@ -436,7 +436,7 @@ class simple_html_dom_node
|
|
436 |
|
437 |
$ret = '';
|
438 |
|
439 |
-
// In rare cases, (always node type 1 or
|
440 |
// for some span tags, and some p tags) $this->nodes is set to NULL.
|
441 |
// NOTE: This indicates that there is a problem where it's set to NULL
|
442 |
// without a clear happening.
|
@@ -472,8 +472,8 @@ class simple_html_dom_node
|
|
472 |
function makeup()
|
473 |
{
|
474 |
// text, comment, unknown
|
475 |
-
if (isset($this->_[
|
476 |
-
return $this->dom->restore_noise($this->_[
|
477 |
}
|
478 |
|
479 |
$ret = '<' . $this->tag;
|
@@ -485,23 +485,23 @@ class simple_html_dom_node
|
|
485 |
// skip removed attribute
|
486 |
if ($val === null || $val === false) { continue; }
|
487 |
|
488 |
-
$ret .= $this->_[
|
489 |
|
490 |
//no value attr: nowrap, checked selected...
|
491 |
if ($val === true) {
|
492 |
$ret .= $key;
|
493 |
} else {
|
494 |
-
switch ($this->_[
|
495 |
{
|
496 |
-
case
|
497 |
-
case
|
498 |
default: $quote = '';
|
499 |
}
|
500 |
|
501 |
$ret .= $key
|
502 |
-
. $this->_[
|
503 |
. '='
|
504 |
-
. $this->_[
|
505 |
. $quote
|
506 |
. $val
|
507 |
. $quote;
|
@@ -509,7 +509,7 @@ class simple_html_dom_node
|
|
509 |
}
|
510 |
|
511 |
$ret = $this->dom->restore_noise($ret);
|
512 |
-
return $ret . $this->_[
|
513 |
}
|
514 |
|
515 |
function find($selector, $idx = null, $lowercase = false)
|
@@ -524,9 +524,9 @@ class simple_html_dom_node
|
|
524 |
// code tracker id 2788009
|
525 |
// used to be: if (($levle=count($selectors[0]))===0) return array();
|
526 |
if (($levle = count($selectors[$c])) === 0) { return array(); }
|
527 |
-
if (!isset($this->_[
|
528 |
|
529 |
-
$head = array($this->_[
|
530 |
$cmd = ' '; // Combinator
|
531 |
|
532 |
// handle descendant selectors, no recursive!
|
@@ -575,18 +575,18 @@ class simple_html_dom_node
|
|
575 |
if ($parent_cmd === ' ') { // Descendant Combinator
|
576 |
// Find parent closing tag if the current element doesn't have a closing
|
577 |
// tag (i.e. void element)
|
578 |
-
$end = (!empty($this->_[
|
579 |
if ($end == 0) {
|
580 |
$parent = $this->parent;
|
581 |
-
while (!isset($parent->_[
|
582 |
$end -= 1;
|
583 |
$parent = $parent->parent;
|
584 |
}
|
585 |
-
$end += $parent->_[
|
586 |
}
|
587 |
|
588 |
// Get list of target nodes
|
589 |
-
$nodes_start = $this->_[
|
590 |
$nodes_count = $end - $nodes_start;
|
591 |
$nodes = array_slice($this->dom->nodes, $nodes_start, $nodes_count, true);
|
592 |
} elseif ($parent_cmd === '>') { // Child Combinator
|
@@ -777,7 +777,7 @@ class simple_html_dom_node
|
|
777 |
}
|
778 |
|
779 |
// Found a match. Add to list and clear node
|
780 |
-
if ($pass) $ret[$node->_[
|
781 |
unset($node);
|
782 |
}
|
783 |
// It's passed by reference so this is actually what this function returns.
|
@@ -990,17 +990,17 @@ class simple_html_dom_node
|
|
990 |
if (is_object($debug_object)) { $debug_object->debug_log_entry(1); }
|
991 |
|
992 |
switch ($name) {
|
993 |
-
case 'outertext': return $this->_[
|
994 |
case 'innertext':
|
995 |
-
if (isset($this->_[
|
996 |
-
return $this->_[
|
997 |
}
|
998 |
-
return $this->_[
|
999 |
}
|
1000 |
|
1001 |
if (!isset($this->attr[$name])) {
|
1002 |
-
$this->_[
|
1003 |
-
$this->_[
|
1004 |
}
|
1005 |
|
1006 |
$this->attr[$name] = $value;
|
@@ -1467,10 +1467,10 @@ class simple_html_dom
|
|
1467 |
$str = null,
|
1468 |
$lowercase = true,
|
1469 |
$forceTagsClosed = true,
|
1470 |
-
$target_charset =
|
1471 |
$stripRN = true,
|
1472 |
-
$defaultBRText =
|
1473 |
-
$defaultSpanText =
|
1474 |
$options = 0)
|
1475 |
{
|
1476 |
if ($str) {
|
@@ -1505,8 +1505,8 @@ class simple_html_dom
|
|
1505 |
$str,
|
1506 |
$lowercase = true,
|
1507 |
$stripRN = true,
|
1508 |
-
$defaultBRText =
|
1509 |
-
$defaultSpanText =
|
1510 |
$options = 0)
|
1511 |
{
|
1512 |
global $debug_object;
|
@@ -1541,14 +1541,14 @@ class simple_html_dom
|
|
1541 |
// strip out server side scripts
|
1542 |
$this->remove_noise("'(<\?)(.*?)(\?>)'s", true);
|
1543 |
|
1544 |
-
if($options &
|
1545 |
$this->remove_noise("'(\{\w)(.*?)(\})'s", true);
|
1546 |
}
|
1547 |
|
1548 |
// parsing
|
1549 |
$this->parse();
|
1550 |
// end
|
1551 |
-
$this->root->_[
|
1552 |
$this->parse_charset();
|
1553 |
|
1554 |
// make load function chainable
|
@@ -1628,8 +1628,8 @@ class simple_html_dom
|
|
1628 |
|
1629 |
protected function prepare(
|
1630 |
$str, $lowercase = true,
|
1631 |
-
$defaultBRText =
|
1632 |
-
$defaultSpanText =
|
1633 |
{
|
1634 |
$this->clear();
|
1635 |
|
@@ -1643,10 +1643,10 @@ class simple_html_dom
|
|
1643 |
$this->lowercase = $lowercase;
|
1644 |
$this->default_br_text = $defaultBRText;
|
1645 |
$this->default_span_text = $defaultSpanText;
|
1646 |
-
$this->root = new
|
1647 |
$this->root->tag = 'root';
|
1648 |
-
$this->root->_[
|
1649 |
-
$this->root->nodetype =
|
1650 |
$this->parent = $this->root;
|
1651 |
if ($this->size > 0) { $this->char = $this->doc[0]; }
|
1652 |
}
|
@@ -1665,9 +1665,9 @@ class simple_html_dom
|
|
1665 |
}
|
1666 |
|
1667 |
// Add a text node for text between tags
|
1668 |
-
$node = new
|
1669 |
++$this->cursor;
|
1670 |
-
$node->_[
|
1671 |
$this->link_nodes($node, false);
|
1672 |
}
|
1673 |
}
|
@@ -1814,7 +1814,7 @@ class simple_html_dom
|
|
1814 |
{
|
1815 |
// Set end position if no further tags found
|
1816 |
if ($this->char !== '<') {
|
1817 |
-
$this->root->_[
|
1818 |
return false;
|
1819 |
}
|
1820 |
|
@@ -1845,7 +1845,7 @@ class simple_html_dom
|
|
1845 |
if (isset($this->optional_closing_tags[$parent_lower])
|
1846 |
&& isset($this->block_tags[$tag_lower])) {
|
1847 |
|
1848 |
-
$this->parent->_[
|
1849 |
$org_parent = $this->parent;
|
1850 |
|
1851 |
// Traverse ancestors to find a matching opening tag
|
@@ -1864,7 +1864,7 @@ class simple_html_dom
|
|
1864 |
$this->parent = $this->parent->parent;
|
1865 |
}
|
1866 |
|
1867 |
-
$this->parent->_[
|
1868 |
return $this->as_text_node($tag);
|
1869 |
}
|
1870 |
} elseif (($this->parent->parent)
|
@@ -1872,7 +1872,7 @@ class simple_html_dom
|
|
1872 |
) {
|
1873 |
// Grandparent exists and current tag is a block tag, so our
|
1874 |
// parent doesn't have an end tag
|
1875 |
-
$this->parent->_[
|
1876 |
$org_parent = $this->parent;
|
1877 |
|
1878 |
// Traverse ancestors to find a matching opening tag
|
@@ -1886,13 +1886,13 @@ class simple_html_dom
|
|
1886 |
// If we don't have a match add current tag as text node
|
1887 |
if (strtolower($this->parent->tag) !== $tag_lower) {
|
1888 |
$this->parent = $org_parent; // restore origonal parent
|
1889 |
-
$this->parent->_[
|
1890 |
return $this->as_text_node($tag);
|
1891 |
}
|
1892 |
} elseif (($this->parent->parent)
|
1893 |
&& strtolower($this->parent->parent->tag) === $tag_lower
|
1894 |
) { // Grandparent exists and current tag closes it
|
1895 |
-
$this->parent->_[
|
1896 |
$this->parent = $this->parent->parent;
|
1897 |
} else { // Random tag, add as text node
|
1898 |
return $this->as_text_node($tag);
|
@@ -1900,7 +1900,7 @@ class simple_html_dom
|
|
1900 |
}
|
1901 |
|
1902 |
// Set end position of parent tag to current cursor position
|
1903 |
-
$this->parent->_[
|
1904 |
|
1905 |
if ($this->parent->parent) {
|
1906 |
$this->parent = $this->parent->parent;
|
@@ -1911,8 +1911,8 @@ class simple_html_dom
|
|
1911 |
}
|
1912 |
|
1913 |
// start tag
|
1914 |
-
$node = new
|
1915 |
-
$node->_[
|
1916 |
++$this->cursor;
|
1917 |
$tag = $this->copy_until($this->token_slash); // Get tag name
|
1918 |
$node->tag_start = $begin_tag_pos;
|
@@ -1922,17 +1922,17 @@ class simple_html_dom
|
|
1922 |
// <![CDATA[ ... ]]>
|
1923 |
// <!-- Comment -->
|
1924 |
if (isset($tag[0]) && $tag[0] === '!') {
|
1925 |
-
$node->_[
|
1926 |
|
1927 |
if (isset($tag[2]) && $tag[1] === '-' && $tag[2] === '-') { // Comment ("<!--")
|
1928 |
-
$node->nodetype =
|
1929 |
$node->tag = 'comment';
|
1930 |
} else { // Could be doctype or CDATA but we don't care
|
1931 |
-
$node->nodetype =
|
1932 |
$node->tag = 'unknown';
|
1933 |
}
|
1934 |
|
1935 |
-
if ($this->char === '>') { $node->_[
|
1936 |
|
1937 |
$this->link_nodes($node, true);
|
1938 |
$this->char = (++$this->pos < $this->size) ? $this->doc[$this->pos] : null; // next
|
@@ -1943,7 +1943,7 @@ class simple_html_dom
|
|
1943 |
// i.e. "<<html>"
|
1944 |
if ($pos = strpos($tag, '<') !== false) {
|
1945 |
$tag = '<' . substr($tag, 0, -1);
|
1946 |
-
$node->_[
|
1947 |
$this->link_nodes($node, false);
|
1948 |
$this->char = $this->doc[--$this->pos]; // prev
|
1949 |
return true;
|
@@ -1951,7 +1951,7 @@ class simple_html_dom
|
|
1951 |
|
1952 |
// Handle invalid tag names (i.e. "<html#doc>")
|
1953 |
if (!preg_match('/^\w[\w:-]*$/', $tag)) {
|
1954 |
-
$node->_[
|
1955 |
|
1956 |
// Next char is the beginning of a new tag, don't touch it.
|
1957 |
if ($this->char === '<') {
|
@@ -1960,14 +1960,14 @@ class simple_html_dom
|
|
1960 |
}
|
1961 |
|
1962 |
// Next char closes current tag, add and be done with it.
|
1963 |
-
if ($this->char === '>') { $node->_[
|
1964 |
$this->link_nodes($node, false);
|
1965 |
$this->char = (++$this->pos < $this->size) ? $this->doc[$this->pos] : null; // next
|
1966 |
return true;
|
1967 |
}
|
1968 |
|
1969 |
// begin tag, add new node
|
1970 |
-
$node->nodetype =
|
1971 |
$tag_lower = strtolower($tag);
|
1972 |
$node->tag = ($this->lowercase) ? $tag_lower : $tag;
|
1973 |
|
@@ -1975,7 +1975,7 @@ class simple_html_dom
|
|
1975 |
if (isset($this->optional_closing_tags[$tag_lower])) {
|
1976 |
// Traverse ancestors to close all optional closing tags
|
1977 |
while (isset($this->optional_closing_tags[$tag_lower][strtolower($this->parent->tag)])) {
|
1978 |
-
$this->parent->_[
|
1979 |
$this->parent = $this->parent->parent;
|
1980 |
}
|
1981 |
$node->parent = $this->parent;
|
@@ -2005,9 +2005,9 @@ class simple_html_dom
|
|
2005 |
// handle endless '<'
|
2006 |
// Out of bounds before the tag ended
|
2007 |
if ($this->pos >= $this->size - 1 && $this->char !== '>') {
|
2008 |
-
$node->nodetype =
|
2009 |
-
$node->_[
|
2010 |
-
$node->_[
|
2011 |
$node->tag = 'text';
|
2012 |
$this->link_nodes($node, false);
|
2013 |
return true;
|
@@ -2016,11 +2016,11 @@ class simple_html_dom
|
|
2016 |
// handle mismatch '<'
|
2017 |
// Attributes cannot start after opening tag
|
2018 |
if ($this->doc[$this->pos - 1] == '<') {
|
2019 |
-
$node->nodetype =
|
2020 |
$node->tag = 'text';
|
2021 |
$node->attr = array();
|
2022 |
-
$node->_[
|
2023 |
-
$node->_[
|
2024 |
$this->doc,
|
2025 |
$begin_tag_pos,
|
2026 |
$this->pos - $begin_tag_pos - 1
|
@@ -2044,12 +2044,12 @@ class simple_html_dom
|
|
2044 |
$this->parse_attr($node, $name, $space); // get attribute value
|
2045 |
} else {
|
2046 |
//no value attr: nowrap, checked selected...
|
2047 |
-
$node->_[
|
2048 |
$node->attr[$name] = true;
|
2049 |
if ($this->char != '>') { $this->char = $this->doc[--$this->pos]; } // prev
|
2050 |
}
|
2051 |
|
2052 |
-
$node->_[
|
2053 |
|
2054 |
// prepare for next attribute
|
2055 |
$space = array(
|
@@ -2063,12 +2063,12 @@ class simple_html_dom
|
|
2063 |
} while ($this->char !== '>' && $this->char !== '/'); // go until the tag ended
|
2064 |
|
2065 |
$this->link_nodes($node, true);
|
2066 |
-
$node->_[
|
2067 |
|
2068 |
// handle empty tags (i.e. "<div/>")
|
2069 |
if ($this->copy_until_char('>') === '/') {
|
2070 |
-
$node->_[
|
2071 |
-
$node->_[
|
2072 |
} else {
|
2073 |
// reset parent
|
2074 |
if (!isset($this->self_closing_tags[strtolower($node->tag)])) {
|
@@ -2082,7 +2082,7 @@ class simple_html_dom
|
|
2082 |
// This way when we see it in plaintext, we can generate formatting that the user wants.
|
2083 |
// since a br tag never has sub nodes, this works well.
|
2084 |
if ($node->tag === 'br') {
|
2085 |
-
$node->_[
|
2086 |
}
|
2087 |
|
2088 |
return true;
|
@@ -2097,19 +2097,19 @@ class simple_html_dom
|
|
2097 |
|
2098 |
switch ($this->char) {
|
2099 |
case '"':
|
2100 |
-
$quote_type =
|
2101 |
$this->char = (++$this->pos < $this->size) ? $this->doc[$this->pos] : null; // next
|
2102 |
$value = $this->copy_until_char('"');
|
2103 |
$this->char = (++$this->pos < $this->size) ? $this->doc[$this->pos] : null; // next
|
2104 |
break;
|
2105 |
case '\'':
|
2106 |
-
$quote_type =
|
2107 |
$this->char = (++$this->pos < $this->size) ? $this->doc[$this->pos] : null; // next
|
2108 |
$value = $this->copy_until_char('\'');
|
2109 |
$this->char = (++$this->pos < $this->size) ? $this->doc[$this->pos] : null; // next
|
2110 |
break;
|
2111 |
default:
|
2112 |
-
$quote_type =
|
2113 |
$value = $this->copy_until($this->token_attr);
|
2114 |
}
|
2115 |
|
@@ -2127,7 +2127,7 @@ class simple_html_dom
|
|
2127 |
}
|
2128 |
|
2129 |
if (!$is_duplicate) {
|
2130 |
-
$node->_[
|
2131 |
$node->attr[$name] = $value;
|
2132 |
}
|
2133 |
}
|
@@ -2143,9 +2143,9 @@ class simple_html_dom
|
|
2143 |
|
2144 |
protected function as_text_node($tag)
|
2145 |
{
|
2146 |
-
$node = new
|
2147 |
++$this->cursor;
|
2148 |
-
$node->_[
|
2149 |
$this->link_nodes($node, false);
|
2150 |
$this->char = (++$this->pos < $this->size) ? $this->doc[$this->pos] : null; // next
|
2151 |
return true;
|
@@ -2323,12 +2323,12 @@ class simple_html_dom
|
|
2323 |
|
2324 |
function createElement($name, $value = null)
|
2325 |
{
|
2326 |
-
return @
|
2327 |
}
|
2328 |
|
2329 |
function createTextNode($value)
|
2330 |
{
|
2331 |
-
return @end(
|
2332 |
}
|
2333 |
|
2334 |
function getElementById($id)
|
26 |
|
27 |
# mod
|
28 |
defined('FVM_MAX_FILE_SIZE') || define('FVM_MAX_FILE_SIZE', 2000000); # Process HTML up to 2 Mb
|
29 |
+
defined('FVMDEFAULT_TARGET_CHARSET') || define('FVMDEFAULT_TARGET_CHARSET', 'UTF-8');
|
30 |
+
defined('FVMDEFAULT_BR_TEXT') || define('FVMDEFAULT_BR_TEXT', "\r\n");
|
31 |
+
defined('FVMDEFAULT_SPAN_TEXT') || define('FVMDEFAULT_SPAN_TEXT', ' ');
|
32 |
|
33 |
# other
|
34 |
+
define('FVMHDOM_TYPE_ELEMENT', 1);
|
35 |
+
define('FVMHDOM_TYPE_COMMENT', 2);
|
36 |
+
define('FVMHDOM_TYPE_TEXT', 3);
|
37 |
+
define('FVMHDOM_TYPE_ENDTAG', 4);
|
38 |
+
define('FVMHDOM_TYPE_ROOT', 5);
|
39 |
+
define('FVMHDOM_TYPE_UNKNOWN', 6);
|
40 |
+
define('FVMHDOM_QUOTE_DOUBLE', 0);
|
41 |
+
define('FVMHDOM_QUOTE_SINGLE', 1);
|
42 |
+
define('FVMHDOM_QUOTE_NO', 3);
|
43 |
+
define('FVMHDOM_INFO_BEGIN', 0);
|
44 |
+
define('FVMHDOM_INFO_END', 1);
|
45 |
+
define('FVMHDOM_INFO_QUOTE', 2);
|
46 |
+
define('FVMHDOM_INFO_SPACE', 3);
|
47 |
+
define('FVMHDOM_INFO_TEXT', 4);
|
48 |
+
define('FVMHDOM_INFO_INNER', 5);
|
49 |
+
define('FVMHDOM_INFO_OUTER', 6);
|
50 |
+
define('FVMHDOM_INFO_ENDSPACE', 7);
|
51 |
+
define('FVMHDOM_SMARTY_AS_TEXT', 1);
|
52 |
|
53 |
# functions
|
54 |
+
function fvm_file_get_html(
|
55 |
$url,
|
56 |
$use_include_path = false,
|
57 |
$context = null,
|
59 |
$maxLen = -1,
|
60 |
$lowercase = true,
|
61 |
$forceTagsClosed = true,
|
62 |
+
$target_charset = FVMDEFAULT_TARGET_CHARSET,
|
63 |
$stripRN = true,
|
64 |
+
$defaultBRText = FVMDEFAULT_BR_TEXT,
|
65 |
+
$defaultSpanText = FVMDEFAULT_SPAN_TEXT)
|
66 |
{
|
67 |
if($maxLen <= 0) { $maxLen = FVM_MAX_FILE_SIZE; }
|
68 |
|
97 |
return $dom->load($contents, $lowercase, $stripRN);
|
98 |
}
|
99 |
|
100 |
+
function fvm_str_get_html(
|
101 |
$str,
|
102 |
$lowercase = true,
|
103 |
$forceTagsClosed = true,
|
104 |
+
$target_charset = FVMDEFAULT_TARGET_CHARSET,
|
105 |
$stripRN = true,
|
106 |
+
$defaultBRText = FVMDEFAULT_BR_TEXT,
|
107 |
+
$defaultSpanText = FVMDEFAULT_SPAN_TEXT)
|
108 |
{
|
109 |
$dom = new simple_html_dom(
|
110 |
null,
|
124 |
return $dom->load($str, $lowercase, $stripRN);
|
125 |
}
|
126 |
|
127 |
+
function fvm_dump_html_tree($node, $show_attr = true, $deep = 0)
|
128 |
{
|
129 |
$node->dump($node);
|
130 |
}
|
131 |
|
132 |
+
class fvm_simple_html_dom_node
|
133 |
{
|
134 |
+
public $nodetype = FVMHDOM_TYPE_TEXT;
|
135 |
public $tag = 'text';
|
136 |
public $attr = array();
|
137 |
public $children = array();
|
218 |
$string .= " text: ({$this->text})";
|
219 |
}
|
220 |
|
221 |
+
$string .= ' FVMHDOM_INNER_INFO: ';
|
222 |
|
223 |
+
if (isset($node->_[FVMHDOM_INFO_INNER])) {
|
224 |
+
$string .= "'" . $node->_[FVMHDOM_INFO_INNER] . "'";
|
225 |
} else {
|
226 |
$string .= ' NULL ';
|
227 |
}
|
345 |
|
346 |
function innertext()
|
347 |
{
|
348 |
+
if (isset($this->_[FVMHDOM_INFO_INNER])) {
|
349 |
+
return $this->_[FVMHDOM_INFO_INNER];
|
350 |
}
|
351 |
|
352 |
+
if (isset($this->_[FVMHDOM_INFO_TEXT])) {
|
353 |
+
return $this->dom->restore_noise($this->_[FVMHDOM_INFO_TEXT]);
|
354 |
}
|
355 |
|
356 |
$ret = '';
|
387 |
call_user_func_array($this->dom->callback, array($this));
|
388 |
}
|
389 |
|
390 |
+
if (isset($this->_[FVMHDOM_INFO_OUTER])) {
|
391 |
+
return $this->_[FVMHDOM_INFO_OUTER];
|
392 |
}
|
393 |
|
394 |
+
if (isset($this->_[FVMHDOM_INFO_TEXT])) {
|
395 |
+
return $this->dom->restore_noise($this->_[FVMHDOM_INFO_TEXT]);
|
396 |
}
|
397 |
|
398 |
$ret = '';
|
399 |
|
400 |
+
if ($this->dom && $this->dom->nodes[$this->_[FVMHDOM_INFO_BEGIN]]) {
|
401 |
+
$ret = $this->dom->nodes[$this->_[FVMHDOM_INFO_BEGIN]]->makeup();
|
402 |
}
|
403 |
|
404 |
+
if (isset($this->_[FVMHDOM_INFO_INNER])) {
|
405 |
+
// todo: <br> should either never have FVMHDOM_INFO_INNER or always
|
406 |
if ($this->tag !== 'br') {
|
407 |
+
$ret .= $this->_[FVMHDOM_INFO_INNER];
|
408 |
}
|
409 |
} elseif ($this->nodes) {
|
410 |
foreach ($this->nodes as $n) {
|
412 |
}
|
413 |
}
|
414 |
|
415 |
+
if (isset($this->_[FVMHDOM_INFO_END]) && $this->_[FVMHDOM_INFO_END] != 0) {
|
416 |
$ret .= '</' . $this->tag . '>';
|
417 |
}
|
418 |
|
421 |
|
422 |
function text()
|
423 |
{
|
424 |
+
if (isset($this->_[FVMHDOM_INFO_INNER])) {
|
425 |
+
return $this->_[FVMHDOM_INFO_INNER];
|
426 |
}
|
427 |
|
428 |
switch ($this->nodetype) {
|
429 |
+
case FVMHDOM_TYPE_TEXT: return $this->dom->restore_noise($this->_[FVMHDOM_INFO_TEXT]);
|
430 |
+
case FVMHDOM_TYPE_COMMENT: return '';
|
431 |
+
case FVMHDOM_TYPE_UNKNOWN: return '';
|
432 |
}
|
433 |
|
434 |
if (strcasecmp($this->tag, 'script') === 0) { return ''; }
|
436 |
|
437 |
$ret = '';
|
438 |
|
439 |
+
// In rare cases, (always node type 1 or FVMHDOM_TYPE_ELEMENT - observed
|
440 |
// for some span tags, and some p tags) $this->nodes is set to NULL.
|
441 |
// NOTE: This indicates that there is a problem where it's set to NULL
|
442 |
// without a clear happening.
|
472 |
function makeup()
|
473 |
{
|
474 |
// text, comment, unknown
|
475 |
+
if (isset($this->_[FVMHDOM_INFO_TEXT])) {
|
476 |
+
return $this->dom->restore_noise($this->_[FVMHDOM_INFO_TEXT]);
|
477 |
}
|
478 |
|
479 |
$ret = '<' . $this->tag;
|
485 |
// skip removed attribute
|
486 |
if ($val === null || $val === false) { continue; }
|
487 |
|
488 |
+
$ret .= $this->_[FVMHDOM_INFO_SPACE][$i][0];
|
489 |
|
490 |
//no value attr: nowrap, checked selected...
|
491 |
if ($val === true) {
|
492 |
$ret .= $key;
|
493 |
} else {
|
494 |
+
switch ($this->_[FVMHDOM_INFO_QUOTE][$i])
|
495 |
{
|
496 |
+
case FVMHDOM_QUOTE_DOUBLE: $quote = '"'; break;
|
497 |
+
case FVMHDOM_QUOTE_SINGLE: $quote = '\''; break;
|
498 |
default: $quote = '';
|
499 |
}
|
500 |
|
501 |
$ret .= $key
|
502 |
+
. $this->_[FVMHDOM_INFO_SPACE][$i][1]
|
503 |
. '='
|
504 |
+
. $this->_[FVMHDOM_INFO_SPACE][$i][2]
|
505 |
. $quote
|
506 |
. $val
|
507 |
. $quote;
|
509 |
}
|
510 |
|
511 |
$ret = $this->dom->restore_noise($ret);
|
512 |
+
return $ret . $this->_[FVMHDOM_INFO_ENDSPACE] . '>';
|
513 |
}
|
514 |
|
515 |
function find($selector, $idx = null, $lowercase = false)
|
524 |
// code tracker id 2788009
|
525 |
// used to be: if (($levle=count($selectors[0]))===0) return array();
|
526 |
if (($levle = count($selectors[$c])) === 0) { return array(); }
|
527 |
+
if (!isset($this->_[FVMHDOM_INFO_BEGIN])) { return array(); }
|
528 |
|
529 |
+
$head = array($this->_[FVMHDOM_INFO_BEGIN] => 1);
|
530 |
$cmd = ' '; // Combinator
|
531 |
|
532 |
// handle descendant selectors, no recursive!
|
575 |
if ($parent_cmd === ' ') { // Descendant Combinator
|
576 |
// Find parent closing tag if the current element doesn't have a closing
|
577 |
// tag (i.e. void element)
|
578 |
+
$end = (!empty($this->_[FVMHDOM_INFO_END])) ? $this->_[FVMHDOM_INFO_END] : 0;
|
579 |
if ($end == 0) {
|
580 |
$parent = $this->parent;
|
581 |
+
while (!isset($parent->_[FVMHDOM_INFO_END]) && $parent !== null) {
|
582 |
$end -= 1;
|
583 |
$parent = $parent->parent;
|
584 |
}
|
585 |
+
$end += $parent->_[FVMHDOM_INFO_END];
|
586 |
}
|
587 |
|
588 |
// Get list of target nodes
|
589 |
+
$nodes_start = $this->_[FVMHDOM_INFO_BEGIN] + 1;
|
590 |
$nodes_count = $end - $nodes_start;
|
591 |
$nodes = array_slice($this->dom->nodes, $nodes_start, $nodes_count, true);
|
592 |
} elseif ($parent_cmd === '>') { // Child Combinator
|
777 |
}
|
778 |
|
779 |
// Found a match. Add to list and clear node
|
780 |
+
if ($pass) $ret[$node->_[FVMHDOM_INFO_BEGIN]] = 1;
|
781 |
unset($node);
|
782 |
}
|
783 |
// It's passed by reference so this is actually what this function returns.
|
990 |
if (is_object($debug_object)) { $debug_object->debug_log_entry(1); }
|
991 |
|
992 |
switch ($name) {
|
993 |
+
case 'outertext': return $this->_[FVMHDOM_INFO_OUTER] = $value;
|
994 |
case 'innertext':
|
995 |
+
if (isset($this->_[FVMHDOM_INFO_TEXT])) {
|
996 |
+
return $this->_[FVMHDOM_INFO_TEXT] = $value;
|
997 |
}
|
998 |
+
return $this->_[FVMHDOM_INFO_INNER] = $value;
|
999 |
}
|
1000 |
|
1001 |
if (!isset($this->attr[$name])) {
|
1002 |
+
$this->_[FVMHDOM_INFO_SPACE][] = array(' ', '', '');
|
1003 |
+
$this->_[FVMHDOM_INFO_QUOTE][] = FVMHDOM_QUOTE_DOUBLE;
|
1004 |
}
|
1005 |
|
1006 |
$this->attr[$name] = $value;
|
1467 |
$str = null,
|
1468 |
$lowercase = true,
|
1469 |
$forceTagsClosed = true,
|
1470 |
+
$target_charset = FVMDEFAULT_TARGET_CHARSET,
|
1471 |
$stripRN = true,
|
1472 |
+
$defaultBRText = FVMDEFAULT_BR_TEXT,
|
1473 |
+
$defaultSpanText = FVMDEFAULT_SPAN_TEXT,
|
1474 |
$options = 0)
|
1475 |
{
|
1476 |
if ($str) {
|
1505 |
$str,
|
1506 |
$lowercase = true,
|
1507 |
$stripRN = true,
|
1508 |
+
$defaultBRText = FVMDEFAULT_BR_TEXT,
|
1509 |
+
$defaultSpanText = FVMDEFAULT_SPAN_TEXT,
|
1510 |
$options = 0)
|
1511 |
{
|
1512 |
global $debug_object;
|
1541 |
// strip out server side scripts
|
1542 |
$this->remove_noise("'(<\?)(.*?)(\?>)'s", true);
|
1543 |
|
1544 |
+
if($options & FVMHDOM_SMARTY_AS_TEXT) { // Strip Smarty scripts
|
1545 |
$this->remove_noise("'(\{\w)(.*?)(\})'s", true);
|
1546 |
}
|
1547 |
|
1548 |
// parsing
|
1549 |
$this->parse();
|
1550 |
// end
|
1551 |
+
$this->root->_[FVMHDOM_INFO_END] = $this->cursor;
|
1552 |
$this->parse_charset();
|
1553 |
|
1554 |
// make load function chainable
|
1628 |
|
1629 |
protected function prepare(
|
1630 |
$str, $lowercase = true,
|
1631 |
+
$defaultBRText = FVMDEFAULT_BR_TEXT,
|
1632 |
+
$defaultSpanText = FVMDEFAULT_SPAN_TEXT)
|
1633 |
{
|
1634 |
$this->clear();
|
1635 |
|
1643 |
$this->lowercase = $lowercase;
|
1644 |
$this->default_br_text = $defaultBRText;
|
1645 |
$this->default_span_text = $defaultSpanText;
|
1646 |
+
$this->root = new fvm_simple_html_dom_node($this);
|
1647 |
$this->root->tag = 'root';
|
1648 |
+
$this->root->_[FVMHDOM_INFO_BEGIN] = -1;
|
1649 |
+
$this->root->nodetype = FVMHDOM_TYPE_ROOT;
|
1650 |
$this->parent = $this->root;
|
1651 |
if ($this->size > 0) { $this->char = $this->doc[0]; }
|
1652 |
}
|
1665 |
}
|
1666 |
|
1667 |
// Add a text node for text between tags
|
1668 |
+
$node = new fvm_simple_html_dom_node($this);
|
1669 |
++$this->cursor;
|
1670 |
+
$node->_[FVMHDOM_INFO_TEXT] = $s;
|
1671 |
$this->link_nodes($node, false);
|
1672 |
}
|
1673 |
}
|
1814 |
{
|
1815 |
// Set end position if no further tags found
|
1816 |
if ($this->char !== '<') {
|
1817 |
+
$this->root->_[FVMHDOM_INFO_END] = $this->cursor;
|
1818 |
return false;
|
1819 |
}
|
1820 |
|
1845 |
if (isset($this->optional_closing_tags[$parent_lower])
|
1846 |
&& isset($this->block_tags[$tag_lower])) {
|
1847 |
|
1848 |
+
$this->parent->_[FVMHDOM_INFO_END] = 0;
|
1849 |
$org_parent = $this->parent;
|
1850 |
|
1851 |
// Traverse ancestors to find a matching opening tag
|
1864 |
$this->parent = $this->parent->parent;
|
1865 |
}
|
1866 |
|
1867 |
+
$this->parent->_[FVMHDOM_INFO_END] = $this->cursor;
|
1868 |
return $this->as_text_node($tag);
|
1869 |
}
|
1870 |
} elseif (($this->parent->parent)
|
1872 |
) {
|
1873 |
// Grandparent exists and current tag is a block tag, so our
|
1874 |
// parent doesn't have an end tag
|
1875 |
+
$this->parent->_[FVMHDOM_INFO_END] = 0; // No end tag
|
1876 |
$org_parent = $this->parent;
|
1877 |
|
1878 |
// Traverse ancestors to find a matching opening tag
|
1886 |
// If we don't have a match add current tag as text node
|
1887 |
if (strtolower($this->parent->tag) !== $tag_lower) {
|
1888 |
$this->parent = $org_parent; // restore origonal parent
|
1889 |
+
$this->parent->_[FVMHDOM_INFO_END] = $this->cursor;
|
1890 |
return $this->as_text_node($tag);
|
1891 |
}
|
1892 |
} elseif (($this->parent->parent)
|
1893 |
&& strtolower($this->parent->parent->tag) === $tag_lower
|
1894 |
) { // Grandparent exists and current tag closes it
|
1895 |
+
$this->parent->_[FVMHDOM_INFO_END] = 0;
|
1896 |
$this->parent = $this->parent->parent;
|
1897 |
} else { // Random tag, add as text node
|
1898 |
return $this->as_text_node($tag);
|
1900 |
}
|
1901 |
|
1902 |
// Set end position of parent tag to current cursor position
|
1903 |
+
$this->parent->_[FVMHDOM_INFO_END] = $this->cursor;
|
1904 |
|
1905 |
if ($this->parent->parent) {
|
1906 |
$this->parent = $this->parent->parent;
|
1911 |
}
|
1912 |
|
1913 |
// start tag
|
1914 |
+
$node = new fvm_simple_html_dom_node($this);
|
1915 |
+
$node->_[FVMHDOM_INFO_BEGIN] = $this->cursor;
|
1916 |
++$this->cursor;
|
1917 |
$tag = $this->copy_until($this->token_slash); // Get tag name
|
1918 |
$node->tag_start = $begin_tag_pos;
|
1922 |
// <![CDATA[ ... ]]>
|
1923 |
// <!-- Comment -->
|
1924 |
if (isset($tag[0]) && $tag[0] === '!') {
|
1925 |
+
$node->_[FVMHDOM_INFO_TEXT] = '<' . $tag . $this->copy_until_char('>');
|
1926 |
|
1927 |
if (isset($tag[2]) && $tag[1] === '-' && $tag[2] === '-') { // Comment ("<!--")
|
1928 |
+
$node->nodetype = FVMHDOM_TYPE_COMMENT;
|
1929 |
$node->tag = 'comment';
|
1930 |
} else { // Could be doctype or CDATA but we don't care
|
1931 |
+
$node->nodetype = FVMHDOM_TYPE_UNKNOWN;
|
1932 |
$node->tag = 'unknown';
|
1933 |
}
|
1934 |
|
1935 |
+
if ($this->char === '>') { $node->_[FVMHDOM_INFO_TEXT] .= '>'; }
|
1936 |
|
1937 |
$this->link_nodes($node, true);
|
1938 |
$this->char = (++$this->pos < $this->size) ? $this->doc[$this->pos] : null; // next
|
1943 |
// i.e. "<<html>"
|
1944 |
if ($pos = strpos($tag, '<') !== false) {
|
1945 |
$tag = '<' . substr($tag, 0, -1);
|
1946 |
+
$node->_[FVMHDOM_INFO_TEXT] = $tag;
|
1947 |
$this->link_nodes($node, false);
|
1948 |
$this->char = $this->doc[--$this->pos]; // prev
|
1949 |
return true;
|
1951 |
|
1952 |
// Handle invalid tag names (i.e. "<html#doc>")
|
1953 |
if (!preg_match('/^\w[\w:-]*$/', $tag)) {
|
1954 |
+
$node->_[FVMHDOM_INFO_TEXT] = '<' . $tag . $this->copy_until('<>');
|
1955 |
|
1956 |
// Next char is the beginning of a new tag, don't touch it.
|
1957 |
if ($this->char === '<') {
|
1960 |
}
|
1961 |
|
1962 |
// Next char closes current tag, add and be done with it.
|
1963 |
+
if ($this->char === '>') { $node->_[FVMHDOM_INFO_TEXT] .= '>'; }
|
1964 |
$this->link_nodes($node, false);
|
1965 |
$this->char = (++$this->pos < $this->size) ? $this->doc[$this->pos] : null; // next
|
1966 |
return true;
|
1967 |
}
|
1968 |
|
1969 |
// begin tag, add new node
|
1970 |
+
$node->nodetype = FVMHDOM_TYPE_ELEMENT;
|
1971 |
$tag_lower = strtolower($tag);
|
1972 |
$node->tag = ($this->lowercase) ? $tag_lower : $tag;
|
1973 |
|
1975 |
if (isset($this->optional_closing_tags[$tag_lower])) {
|
1976 |
// Traverse ancestors to close all optional closing tags
|
1977 |
while (isset($this->optional_closing_tags[$tag_lower][strtolower($this->parent->tag)])) {
|
1978 |
+
$this->parent->_[FVMHDOM_INFO_END] = 0;
|
1979 |
$this->parent = $this->parent->parent;
|
1980 |
}
|
1981 |
$node->parent = $this->parent;
|
2005 |
// handle endless '<'
|
2006 |
// Out of bounds before the tag ended
|
2007 |
if ($this->pos >= $this->size - 1 && $this->char !== '>') {
|
2008 |
+
$node->nodetype = FVMHDOM_TYPE_TEXT;
|
2009 |
+
$node->_[FVMHDOM_INFO_END] = 0;
|
2010 |
+
$node->_[FVMHDOM_INFO_TEXT] = '<' . $tag . $space[0] . $name;
|
2011 |
$node->tag = 'text';
|
2012 |
$this->link_nodes($node, false);
|
2013 |
return true;
|
2016 |
// handle mismatch '<'
|
2017 |
// Attributes cannot start after opening tag
|
2018 |
if ($this->doc[$this->pos - 1] == '<') {
|
2019 |
+
$node->nodetype = FVMHDOM_TYPE_TEXT;
|
2020 |
$node->tag = 'text';
|
2021 |
$node->attr = array();
|
2022 |
+
$node->_[FVMHDOM_INFO_END] = 0;
|
2023 |
+
$node->_[FVMHDOM_INFO_TEXT] = substr(
|
2024 |
$this->doc,
|
2025 |
$begin_tag_pos,
|
2026 |
$this->pos - $begin_tag_pos - 1
|
2044 |
$this->parse_attr($node, $name, $space); // get attribute value
|
2045 |
} else {
|
2046 |
//no value attr: nowrap, checked selected...
|
2047 |
+
$node->_[FVMHDOM_INFO_QUOTE][] = FVMHDOM_QUOTE_NO;
|
2048 |
$node->attr[$name] = true;
|
2049 |
if ($this->char != '>') { $this->char = $this->doc[--$this->pos]; } // prev
|
2050 |
}
|
2051 |
|
2052 |
+
$node->_[FVMHDOM_INFO_SPACE][] = $space;
|
2053 |
|
2054 |
// prepare for next attribute
|
2055 |
$space = array(
|
2063 |
} while ($this->char !== '>' && $this->char !== '/'); // go until the tag ended
|
2064 |
|
2065 |
$this->link_nodes($node, true);
|
2066 |
+
$node->_[FVMHDOM_INFO_ENDSPACE] = $space[0];
|
2067 |
|
2068 |
// handle empty tags (i.e. "<div/>")
|
2069 |
if ($this->copy_until_char('>') === '/') {
|
2070 |
+
$node->_[FVMHDOM_INFO_ENDSPACE] .= '/';
|
2071 |
+
$node->_[FVMHDOM_INFO_END] = 0;
|
2072 |
} else {
|
2073 |
// reset parent
|
2074 |
if (!isset($this->self_closing_tags[strtolower($node->tag)])) {
|
2082 |
// This way when we see it in plaintext, we can generate formatting that the user wants.
|
2083 |
// since a br tag never has sub nodes, this works well.
|
2084 |
if ($node->tag === 'br') {
|
2085 |
+
$node->_[FVMHDOM_INFO_INNER] = $this->default_br_text;
|
2086 |
}
|
2087 |
|
2088 |
return true;
|
2097 |
|
2098 |
switch ($this->char) {
|
2099 |
case '"':
|
2100 |
+
$quote_type = FVMHDOM_QUOTE_DOUBLE;
|
2101 |
$this->char = (++$this->pos < $this->size) ? $this->doc[$this->pos] : null; // next
|
2102 |
$value = $this->copy_until_char('"');
|
2103 |
$this->char = (++$this->pos < $this->size) ? $this->doc[$this->pos] : null; // next
|
2104 |
break;
|
2105 |
case '\'':
|
2106 |
+
$quote_type = FVMHDOM_QUOTE_SINGLE;
|
2107 |
$this->char = (++$this->pos < $this->size) ? $this->doc[$this->pos] : null; // next
|
2108 |
$value = $this->copy_until_char('\'');
|
2109 |
$this->char = (++$this->pos < $this->size) ? $this->doc[$this->pos] : null; // next
|
2110 |
break;
|
2111 |
default:
|
2112 |
+
$quote_type = FVMHDOM_QUOTE_NO;
|
2113 |
$value = $this->copy_until($this->token_attr);
|
2114 |
}
|
2115 |
|
2127 |
}
|
2128 |
|
2129 |
if (!$is_duplicate) {
|
2130 |
+
$node->_[FVMHDOM_INFO_QUOTE][] = $quote_type;
|
2131 |
$node->attr[$name] = $value;
|
2132 |
}
|
2133 |
}
|
2143 |
|
2144 |
protected function as_text_node($tag)
|
2145 |
{
|
2146 |
+
$node = new fvm_simple_html_dom_node($this);
|
2147 |
++$this->cursor;
|
2148 |
+
$node->_[FVMHDOM_INFO_TEXT] = '</' . $tag . '>';
|
2149 |
$this->link_nodes($node, false);
|
2150 |
$this->char = (++$this->pos < $this->size) ? $this->doc[$this->pos] : null; // next
|
2151 |
return true;
|
2323 |
|
2324 |
function createElement($name, $value = null)
|
2325 |
{
|
2326 |
+
return @fvm_str_get_html("<$name>$value</$name>")->firstChild();
|
2327 |
}
|
2328 |
|
2329 |
function createTextNode($value)
|
2330 |
{
|
2331 |
+
return @end(fvm_str_get_html($value)->nodes);
|
2332 |
}
|
2333 |
|
2334 |
function getElementById($id)
|
readme.txt
CHANGED
@@ -3,13 +3,13 @@ Contributors: Alignak
|
|
3 |
Tags: PHP Minify, Lighthouse, GTmetrix, Pingdom, Pagespeed, Merging, Minification, Optimization, Speed, Performance, FVM
|
4 |
Requires at least: 4.9
|
5 |
Requires PHP: 5.6
|
6 |
-
Stable tag: 3.2.
|
7 |
-
Tested up to: 5.
|
8 |
Text Domain: fast-velocity-minify
|
9 |
License: GPLv3 or later
|
10 |
License URI: http://www.gnu.org/licenses/gpl-3.0.html
|
11 |
|
12 |
-
Improve your speed score on GTmetrix, Pingdom Tools and Google PageSpeed Insights by adjusting
|
13 |
|
14 |
|
15 |
== Description ==
|
@@ -49,8 +49,18 @@ You need a public directory to store and serve minified cache files. If you need
|
|
49 |
|
50 |
== Changelog ==
|
51 |
|
52 |
-
= 3.2.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
53 |
* added auto varnish cache purge for Cloudways
|
|
|
|
|
|
|
54 |
* fixed some JS files not being minified
|
55 |
|
56 |
= 3.2.1 [2021.05.07] =
|
3 |
Tags: PHP Minify, Lighthouse, GTmetrix, Pingdom, Pagespeed, Merging, Minification, Optimization, Speed, Performance, FVM
|
4 |
Requires at least: 4.9
|
5 |
Requires PHP: 5.6
|
6 |
+
Stable tag: 3.2.4
|
7 |
+
Tested up to: 5.9.1
|
8 |
Text Domain: fast-velocity-minify
|
9 |
License: GPLv3 or later
|
10 |
License URI: http://www.gnu.org/licenses/gpl-3.0.html
|
11 |
|
12 |
+
Improve your speed score on GTmetrix, Pingdom Tools and Google PageSpeed Insights by adjusting CSS and JS files (defer, async, minify, combine, etc), compressing HTML, simplifying fonts and a few more speed optimization options.
|
13 |
|
14 |
|
15 |
== Description ==
|
49 |
|
50 |
== Changelog ==
|
51 |
|
52 |
+
= 3.2.4 [2022.01.31] =
|
53 |
+
* WP 5.9 / PHP 8 maintenance release
|
54 |
+
* changed deferred css/js cache clearing from 24h to 7 days
|
55 |
+
* added cache purging support for nginx helper plugin
|
56 |
+
* added option to allow processing on specific query strings
|
57 |
+
* other bug fixes
|
58 |
+
|
59 |
+
= 3.2.3 [2021.05.15] =
|
60 |
* added auto varnish cache purge for Cloudways
|
61 |
+
* switched from WP_Filesystem_Direct() to WP_Filesystem()
|
62 |
+
|
63 |
+
= 3.2.2 [2021.05.09] =
|
64 |
* fixed some JS files not being minified
|
65 |
|
66 |
= 3.2.1 [2021.05.07] =
|