Version Description
[2021.04.24] = * added support for WP Cloudflare Super Page Cache plugin * fixed support for LiteSpeed Cache purging * changed the cache directory to the uploads directory (WP_Filesystem_Direct) * deprecated CSS and JS merging as this is no longer recommended for HTTP/2 servers * stop removing RSS feeds references on the header cleanup option * changed some descriptions and updated the HELP section * other bug fixes
Download this release
Release Info
Developer | Alignak |
Plugin | Fast Velocity Minify |
Version | 3.1.5 |
Comparing to | |
See all releases |
Code changes from version 3.1.4 to 3.1.5
- assets/fvm.js +12 -19
- fvm.php +1 -4
- inc/admin.php +109 -243
- inc/common.php +1003 -613
- inc/frontend.php +793 -779
- layout/admin-layout-help.php +93 -120
- layout/admin-layout-settings.php +62 -94
- layout/admin-layout-status.php +3 -14
- libs/raisermin/minify.php +27 -108
- readme.txt +16 -7
assets/fvm.js
CHANGED
@@ -3,26 +3,19 @@ function fvm_get_logs() {
|
|
3 |
|
4 |
// ajax request
|
5 |
jQuery( document ).ready(function() {
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
|
|
12 |
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
jQuery('textarea.log-js').val(resp.js_log);
|
19 |
-
jQuery('textarea.log-js').scrollTop(0);
|
20 |
-
|
21 |
-
} else {
|
22 |
-
// error log
|
23 |
-
console.error(resp.success);
|
24 |
-
}
|
25 |
-
});
|
26 |
});
|
27 |
}
|
28 |
|
3 |
|
4 |
// ajax request
|
5 |
jQuery( document ).ready(function() {
|
6 |
+
var data = { 'action': 'fvm_get_logs' };
|
7 |
+
jQuery.post(ajaxurl, data, function(resp) {
|
8 |
+
if(resp.success == 'OK') {
|
9 |
+
|
10 |
+
// logs
|
11 |
+
jQuery('.log-stats textarea').val(resp.log);
|
12 |
+
jQuery('.log-stats textarea').scrollTop(jQuery('.log-stats textarea')[0].scrollHeight);
|
13 |
|
14 |
+
} else {
|
15 |
+
// error log
|
16 |
+
console.error(resp.success);
|
17 |
+
}
|
18 |
+
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
});
|
20 |
}
|
21 |
|
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.1.
|
10 |
License: GPL2
|
11 |
|
12 |
------------------------------------------------------------------------
|
@@ -54,9 +54,6 @@ if (defined('WP_CLI') && WP_CLI) {
|
|
54 |
# get all options from database
|
55 |
$fvm_settings = fvm_get_settings();
|
56 |
|
57 |
-
# get cache paths and info
|
58 |
-
$fvm_cache_paths = fvm_cachepath();
|
59 |
-
|
60 |
# site url, domain name
|
61 |
$fvm_urls = array('wp_site_url'=>site_url(), 'wp_domain'=>fvm_get_domain());
|
62 |
|
6 |
Author: Raul Peixoto
|
7 |
Author URI: http://fastvelocity.com
|
8 |
Text Domain: fast-velocity-minify
|
9 |
+
Version: 3.1.5
|
10 |
License: GPL2
|
11 |
|
12 |
------------------------------------------------------------------------
|
54 |
# get all options from database
|
55 |
$fvm_settings = fvm_get_settings();
|
56 |
|
|
|
|
|
|
|
57 |
# site url, domain name
|
58 |
$fvm_urls = array('wp_site_url'=>site_url(), 'wp_domain'=>fvm_get_domain());
|
59 |
|
inc/admin.php
CHANGED
@@ -45,24 +45,45 @@ function fvm_check_minimum_requirements() {
|
|
45 |
|
46 |
# check for soft errors and misconfiguration
|
47 |
function fvm_check_misconfiguration() {
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
56 |
}
|
57 |
|
58 |
-
#
|
59 |
-
if(
|
60 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
}
|
62 |
|
63 |
-
|
64 |
-
fvm_initialize_database();
|
65 |
-
|
66 |
}
|
67 |
}
|
68 |
|
@@ -229,155 +250,40 @@ function fvm_get_logs_callback() {
|
|
229 |
|
230 |
# must be able to cleanup cache
|
231 |
if (!current_user_can('manage_options')) {
|
232 |
-
wp_die( __('You do not have sufficient permissions to access this page.'
|
233 |
}
|
234 |
|
235 |
# must have
|
236 |
if(!defined('WP_CONTENT_DIR')) {
|
237 |
-
wp_die( __('WP_CONTENT_DIR is undefined!'
|
238 |
}
|
239 |
|
240 |
-
#
|
241 |
-
global $
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
# defaults
|
247 |
-
$count_css = 0;
|
248 |
-
$count_js = 0;
|
249 |
-
$size_css = 0;
|
250 |
-
$size_js = 0;
|
251 |
|
252 |
-
|
253 |
-
|
254 |
-
if(is_dir($fvm_cache_paths['cache_dir_min'])) {
|
255 |
-
try {
|
256 |
-
$i = new DirectoryIterator($fvm_cache_paths['cache_dir_min']);
|
257 |
-
foreach($i as $f){
|
258 |
-
if($f->isFile()){
|
259 |
-
|
260 |
-
# javascript
|
261 |
-
if(stripos($f->getRealPath(), '.js') !== false) {
|
262 |
-
$count_js = $count_js + 1;
|
263 |
-
$size_js = $size_js + intval($f->getSize());
|
264 |
-
}
|
265 |
-
|
266 |
-
# css
|
267 |
-
if(stripos($f->getRealPath(), '.css') !== false) {
|
268 |
-
$count_css = $count_css + 1;
|
269 |
-
$size_css = $size_css + intval($f->getSize());
|
270 |
-
}
|
271 |
-
|
272 |
-
}
|
273 |
-
}
|
274 |
-
} catch (Exception $e) {
|
275 |
-
$errora = get_class($e) . ": " . $e->getMessage();
|
276 |
-
}
|
277 |
-
}
|
278 |
-
|
279 |
-
# return early if errors
|
280 |
-
if($errora != false) {
|
281 |
-
header('Content-Type: application/json');
|
282 |
-
echo json_encode(array('error' => $errora));
|
283 |
-
exit();
|
284 |
-
}
|
285 |
-
|
286 |
|
287 |
-
|
288 |
-
|
289 |
-
$tbl_name_log = $wpdb->prefix .'fvm_logs';
|
290 |
-
$tbl_name_cache = $wpdb->prefix .'fvm_cache';
|
291 |
-
|
292 |
-
# initialize log
|
293 |
-
$css_log = '';
|
294 |
-
|
295 |
-
# build css logs from database
|
296 |
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
# get meta into an array
|
303 |
-
$meta = json_decode($log->meta, true);
|
304 |
-
|
305 |
-
# start log
|
306 |
-
$css_log.= '+++++++++' . PHP_EOL;
|
307 |
-
$css_log.= 'PROCESSED - ' . date('r', $log->date) . ' - VIA - '. $meta['loc'] . PHP_EOL;
|
308 |
-
$css_log.= 'GENERATED - ' . $meta['fl'] . PHP_EOL;
|
309 |
-
$css_log.= 'MEDIATYPE - ' . $meta['mt'] . PHP_EOL;
|
310 |
-
$css_log.= '---' . PHP_EOL;
|
311 |
-
|
312 |
-
# generate uid's from json
|
313 |
-
$list = array(); $list = json_decode($log->content);
|
314 |
-
|
315 |
-
# get rows to log file
|
316 |
-
if(count($list) > 0) {
|
317 |
-
$listuids = implode(', ', array_fill(0, count($list), '%s'));
|
318 |
-
if(!empty($listuids)) {
|
319 |
-
$rs = array(); $rs = $wpdb->get_results($wpdb->prepare("SELECT meta FROM `$tbl_name_cache` WHERE uid IN (".$listuids.") ORDER BY FIELD(uid, '".implode("', '", $list)."')", $list));
|
320 |
-
foreach ($rs as $r) {
|
321 |
-
$imt = json_decode($r->meta, true);
|
322 |
-
$css_log.= '[Size: '.str_pad(fvm_format_filesize($imt['fs']), 10,' ',STR_PAD_LEFT).']'."\t". $imt['url'] . PHP_EOL;
|
323 |
-
}
|
324 |
-
}
|
325 |
-
$css_log.= '+++++++++' . PHP_EOL . PHP_EOL;
|
326 |
-
}
|
327 |
}
|
328 |
-
|
329 |
-
|
330 |
-
|
|
|
331 |
|
332 |
-
# initialize log
|
333 |
-
$js_log = '';
|
334 |
-
|
335 |
-
# build css logs from database
|
336 |
-
$results = $wpdb->get_results("SELECT date, content, meta FROM `$tbl_name_log` WHERE type = 'js' ORDER BY id DESC LIMIT 20");
|
337 |
-
|
338 |
-
# build second query
|
339 |
-
foreach ($results as $log) {
|
340 |
-
|
341 |
-
# get meta into an array
|
342 |
-
$meta = json_decode($log->meta, true);
|
343 |
-
|
344 |
-
# start log
|
345 |
-
$js_log.= '+++++++++' . PHP_EOL;
|
346 |
-
$js_log.= __( 'PROCESSED', 'fast-velocity-minify' ) . ' - ' . date('r', $log->date) . ' - VIA - '. $meta['loc'] . PHP_EOL;
|
347 |
-
$js_log.= __( 'GENERATED', 'fast-velocity-minify' ) . ' - ' . $meta['fl'] . PHP_EOL;
|
348 |
-
$js_log.= '---' . PHP_EOL;
|
349 |
-
|
350 |
-
# generate uid's from json
|
351 |
-
$list = array(); $list = json_decode($log->content);
|
352 |
-
|
353 |
-
# get rows to log file
|
354 |
-
if(count($list) > 0) {
|
355 |
-
$listuids = implode(', ', array_fill(0, count($list), '%s'));
|
356 |
-
if(!empty($listuids)) {
|
357 |
-
$rs = array(); $rs = $wpdb->get_results($wpdb->prepare("SELECT meta FROM `$tbl_name_cache` WHERE uid IN (".$listuids.") ORDER BY FIELD(uid, '".implode("', '", $list)."')", $list));
|
358 |
-
foreach ($rs as $r) {
|
359 |
-
$imt = json_decode($r->meta, true);
|
360 |
-
$js_log.= '['.__( 'Size:', 'fast-velocity-minify' ).' '.str_pad(fvm_format_filesize($imt['fs']), 10,' ',STR_PAD_LEFT).']'."\t". $imt['url'] . PHP_EOL;
|
361 |
-
}
|
362 |
-
}
|
363 |
-
$js_log.= '+++++++++' . PHP_EOL . PHP_EOL;
|
364 |
-
}
|
365 |
-
}
|
366 |
-
|
367 |
-
# trim
|
368 |
-
$js_log = trim($js_log);
|
369 |
-
|
370 |
-
# default message
|
371 |
-
if(empty($css_log)) { $css_log = __( 'No CSS files generated yet.', 'fast-velocity-minify' ); }
|
372 |
-
if(empty($js_log)) { $js_log = __( 'No JS files generated yet.', 'fast-velocity-minify' ); }
|
373 |
-
|
374 |
# build info
|
375 |
$result = array(
|
376 |
-
'
|
377 |
-
'stats_css' => array('count'=>$count_css, 'size'=>fvm_format_filesize($size_css)),
|
378 |
-
'stats_js' => array('count'=>$count_js, 'size'=>fvm_format_filesize($size_js)),
|
379 |
-
'js_log' => $js_log,
|
380 |
-
'css_log' => $css_log,
|
381 |
'success' => 'OK'
|
382 |
);
|
383 |
|
@@ -385,11 +291,7 @@ function fvm_get_logs_callback() {
|
|
385 |
header('Content-Type: application/json');
|
386 |
echo json_encode($result);
|
387 |
exit();
|
388 |
-
|
389 |
-
}
|
390 |
|
391 |
-
# default
|
392 |
-
wp_die( __('Unknown cache path!', 'fast-velocity-minify'), __('Error:', 'fast-velocity-minify'), array('response'=>200));
|
393 |
}
|
394 |
|
395 |
|
@@ -397,47 +299,47 @@ function fvm_get_logs_callback() {
|
|
397 |
register_activation_hook($fvm_var_file, 'fvm_plugin_activate');
|
398 |
function fvm_plugin_activate() {
|
399 |
|
400 |
-
# default variables
|
401 |
global $wpdb;
|
402 |
-
$
|
403 |
-
|
404 |
-
|
|
|
|
|
405 |
|
406 |
-
#
|
407 |
-
$
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
|
|
|
|
418 |
|
419 |
# create logs table
|
420 |
-
|
421 |
-
$sqlb = "CREATE TABLE IF NOT EXISTS
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
|
|
433 |
|
434 |
# run sql
|
435 |
-
|
436 |
-
|
437 |
-
dbDelta( $sqlb );
|
438 |
-
|
439 |
-
# initialize cache time
|
440 |
-
fvm_cache_increment();
|
441 |
|
442 |
}
|
443 |
|
@@ -445,71 +347,35 @@ function fvm_plugin_activate() {
|
|
445 |
# run during deactivation
|
446 |
register_deactivation_hook($fvm_var_file, 'fvm_plugin_deactivate');
|
447 |
function fvm_plugin_deactivate() {
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
if(isset($fvm_cache_paths['cache_dir_min']) && stripos($fvm_cache_paths['cache_dir_min'], '/fvm') !== false) {
|
452 |
-
fvm_rrmdir($fvm_cache_paths['cache_base_dir']);
|
453 |
-
}
|
454 |
|
455 |
-
#
|
456 |
-
$
|
457 |
-
$
|
458 |
-
$wpdb->query($
|
459 |
|
460 |
-
#
|
461 |
-
|
462 |
-
$sql = $wpdb->prepare( "DROP TABLE IF EXISTS `$tbl_name`", $tbl_name);
|
463 |
-
$wpdb->query($sql);
|
464 |
|
465 |
}
|
466 |
|
467 |
# run during uninstall
|
468 |
register_uninstall_hook($fvm_var_file, 'fvm_plugin_uninstall');
|
469 |
function fvm_plugin_uninstall() {
|
470 |
-
global $wpdb
|
471 |
-
|
472 |
-
# fetch settings on wp-cli
|
473 |
-
if(is_null($fvm_settings)) { $fvm_settings = fvm_get_settings(); }
|
474 |
-
if(is_null($fvm_cache_paths)) { $fvm_cache_paths = fvm_cachepath(); }
|
475 |
-
|
476 |
-
# remove settings, unless disabled
|
477 |
-
if(!isset($fvm_settings['global']['preserve_settings']) || ( isset($fvm_settings['global']['preserve_settings']) && $fvm_settings['global']['preserve_settings'] != true)) {
|
478 |
-
|
479 |
-
# prepare and delete
|
480 |
-
$tbl_name = $wpdb->prefix .'options';
|
481 |
-
$sql = $wpdb->prepare( "DELETE FROM `$tbl_name` WHERE option_name = 'fvm_settings'");
|
482 |
-
$wpdb->query($sql);
|
483 |
-
$sql = $wpdb->prepare( "DELETE FROM `$tbl_name` WHERE option_name = 'fvm_last_cache_update'");
|
484 |
-
$wpdb->query($sql);
|
485 |
-
|
486 |
-
}
|
487 |
|
488 |
-
#
|
489 |
-
$
|
490 |
-
$
|
491 |
-
$wpdb->query($
|
|
|
492 |
|
493 |
-
#
|
494 |
-
|
495 |
-
$sql = $wpdb->prepare( "DROP TABLE IF EXISTS `$tbl_name`");
|
496 |
-
$wpdb->query($sql);
|
497 |
|
498 |
-
# remove all cache directories
|
499 |
-
if(isset($fvm_cache_paths['cache_dir_min']) && stripos($fvm_cache_paths['cache_dir_min'], '/fvm') !== false) {
|
500 |
-
fvm_rrmdir($fvm_cache_paths['cache_base_dir']);
|
501 |
-
}
|
502 |
-
}
|
503 |
-
|
504 |
-
# initialize database if it doesn't exist
|
505 |
-
function fvm_initialize_database() {
|
506 |
-
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
|
507 |
-
global $wpdb;
|
508 |
-
$tbl_name = $wpdb->prefix .'fvm_cache';
|
509 |
-
$sql = $wpdb->prepare( 'SHOW TABLES LIKE %s', $wpdb->esc_like( $tbl_name ) );
|
510 |
-
if ( $wpdb->get_var( $sql ) !== $tbl_name ) {
|
511 |
-
fvm_plugin_activate();
|
512 |
-
}
|
513 |
}
|
514 |
|
515 |
|
45 |
|
46 |
# check for soft errors and misconfiguration
|
47 |
function fvm_check_misconfiguration() {
|
48 |
+
try {
|
49 |
+
|
50 |
+
# plugin version
|
51 |
+
global $fvm_var_plugin_version;
|
52 |
+
if(is_null($fvm_var_plugin_version)) { return false; }
|
53 |
+
|
54 |
+
# if no database version, regenerate
|
55 |
+
$plugin_meta = get_option('fvm_plugin_meta');
|
56 |
+
if($plugin_meta === false) {
|
57 |
+
|
58 |
+
# startup routines
|
59 |
+
fvm_plugin_deactivate();
|
60 |
+
fvm_plugin_activate();
|
61 |
+
|
62 |
+
# save
|
63 |
+
update_option('fvm_plugin_meta', json_encode(array('dbv'=>0)) );
|
64 |
}
|
65 |
|
66 |
+
# updates
|
67 |
+
if($plugin_meta !== false) {
|
68 |
+
|
69 |
+
# future updates
|
70 |
+
$meta = json_decode($plugin_meta, true);
|
71 |
+
$previous_version = $meta['dbv'];
|
72 |
+
if($fvm_var_plugin_version != $previous_version) {
|
73 |
+
|
74 |
+
# startup routines
|
75 |
+
fvm_plugin_deactivate();
|
76 |
+
fvm_plugin_activate();
|
77 |
+
|
78 |
+
# save
|
79 |
+
update_option('fvm_plugin_meta', json_encode(array('dbv'=>$fvm_var_plugin_version)) );
|
80 |
+
|
81 |
+
}
|
82 |
+
|
83 |
}
|
84 |
|
85 |
+
} catch (Exception $e) {
|
86 |
+
error_log('Caught exception (fvm_initialize_database): '.$e->getMessage(), 0);
|
|
|
87 |
}
|
88 |
}
|
89 |
|
250 |
|
251 |
# must be able to cleanup cache
|
252 |
if (!current_user_can('manage_options')) {
|
253 |
+
wp_die( __('You do not have sufficient permissions to access this page.'), __('Error:'), array('response'=>200));
|
254 |
}
|
255 |
|
256 |
# must have
|
257 |
if(!defined('WP_CONTENT_DIR')) {
|
258 |
+
wp_die( __('WP_CONTENT_DIR is undefined!'), __('Error:'), array('response'=>200));
|
259 |
}
|
260 |
|
261 |
+
# defaults
|
262 |
+
global $wpdb;
|
263 |
+
if(is_null($wpdb)) {
|
264 |
+
wp_die( __('Database error!'), __('Error:'), array('response'=>200));
|
265 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
266 |
|
267 |
+
# initialize log
|
268 |
+
$log = '';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
269 |
|
270 |
+
# build css logs from database
|
271 |
+
$results = $wpdb->get_results("SELECT date, msg FROM ".$wpdb->prefix."fvm_logs ORDER BY id DESC LIMIT 500", 'ARRAY_A');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
272 |
|
273 |
+
# build log
|
274 |
+
if(is_array($results)) {
|
275 |
+
foreach (array_reverse($results, true) as $r) {
|
276 |
+
$log.= 'PROCESSED ON - ' . date('r', $r['date']) . PHP_EOL;
|
277 |
+
$log.= $r['msg'] . PHP_EOL . PHP_EOL;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
278 |
}
|
279 |
+
}
|
280 |
+
|
281 |
+
# default message
|
282 |
+
if(empty($log)) { $log = 'No logs generated yet.'; }
|
283 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
284 |
# build info
|
285 |
$result = array(
|
286 |
+
'log' => $log,
|
|
|
|
|
|
|
|
|
287 |
'success' => 'OK'
|
288 |
);
|
289 |
|
291 |
header('Content-Type: application/json');
|
292 |
echo json_encode($result);
|
293 |
exit();
|
|
|
|
|
294 |
|
|
|
|
|
295 |
}
|
296 |
|
297 |
|
299 |
register_activation_hook($fvm_var_file, 'fvm_plugin_activate');
|
300 |
function fvm_plugin_activate() {
|
301 |
|
|
|
302 |
global $wpdb;
|
303 |
+
if(is_null($wpdb)) { return false; }
|
304 |
+
|
305 |
+
# defauls
|
306 |
+
$sql = array();
|
307 |
+
$wpdb_collate = $wpdb->collate;
|
308 |
|
309 |
+
# create cache table
|
310 |
+
$sqla_table_name = $wpdb->prefix . 'fvm_cache';
|
311 |
+
$sqla = "CREATE TABLE IF NOT EXISTS {$sqla_table_name} (
|
312 |
+
`id` bigint(20) unsigned NOT NULL auto_increment ,
|
313 |
+
`uid` varchar(64) NOT NULL,
|
314 |
+
`date` bigint(10) unsigned NOT NULL,
|
315 |
+
`type` varchar(3) NOT NULL,
|
316 |
+
`content` mediumtext NOT NULL,
|
317 |
+
`meta` mediumtext NOT NULL,
|
318 |
+
PRIMARY KEY (id),
|
319 |
+
UNIQUE KEY uid (uid),
|
320 |
+
KEY date (date), KEY type (type)
|
321 |
+
)
|
322 |
+
COLLATE {$wpdb_collate}";
|
323 |
|
324 |
# create logs table
|
325 |
+
$sqlb_table_name = $wpdb->prefix . 'fvm_logs';
|
326 |
+
$sqlb = "CREATE TABLE IF NOT EXISTS {$sqlb_table_name} (
|
327 |
+
`id` bigint(20) unsigned NOT NULL auto_increment,
|
328 |
+
`uid` varchar(64) NOT NULL,
|
329 |
+
`date` bigint(10) unsigned NOT NULL,
|
330 |
+
`type` varchar(10) NOT NULL,
|
331 |
+
`msg` mediumtext NOT NULL,
|
332 |
+
`meta` mediumtext NOT NULL,
|
333 |
+
PRIMARY KEY (id),
|
334 |
+
UNIQUE KEY uid (uid),
|
335 |
+
KEY date (date),
|
336 |
+
KEY type (type)
|
337 |
+
)
|
338 |
+
COLLATE {$wpdb_collate}";
|
339 |
|
340 |
# run sql
|
341 |
+
$wpdb->query($sqla);
|
342 |
+
$wpdb->query($sqlb);
|
|
|
|
|
|
|
|
|
343 |
|
344 |
}
|
345 |
|
347 |
# run during deactivation
|
348 |
register_deactivation_hook($fvm_var_file, 'fvm_plugin_deactivate');
|
349 |
function fvm_plugin_deactivate() {
|
350 |
+
|
351 |
+
global $wpdb;
|
352 |
+
if(is_null($wpdb)) { return false; }
|
|
|
|
|
|
|
353 |
|
354 |
+
# remove options and tables
|
355 |
+
$wpdb->query("DELETE FROM {$wpdb->prefix}options WHERE option_name = 'fvm_last_cache_update'");
|
356 |
+
$wpdb->query("DROP TABLE IF EXISTS {$wpdb->prefix}fvm_cache");
|
357 |
+
$wpdb->query("DROP TABLE IF EXISTS {$wpdb->prefix}fvm_logs");
|
358 |
|
359 |
+
# process cache settings
|
360 |
+
fvm_purge_static_files();
|
|
|
|
|
361 |
|
362 |
}
|
363 |
|
364 |
# run during uninstall
|
365 |
register_uninstall_hook($fvm_var_file, 'fvm_plugin_uninstall');
|
366 |
function fvm_plugin_uninstall() {
|
367 |
+
global $wpdb;
|
368 |
+
if(is_null($wpdb)) { return false; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
369 |
|
370 |
+
# remove options and tables
|
371 |
+
$wpdb->query("DELETE FROM {$wpdb->prefix}options WHERE option_name = 'fvm_settings'");
|
372 |
+
$wpdb->query("DELETE FROM {$wpdb->prefix}options WHERE option_name = 'fvm_last_cache_update'");
|
373 |
+
$wpdb->query("DROP TABLE IF EXISTS {$wpdb->prefix}fvm_cache");
|
374 |
+
$wpdb->query("DROP TABLE IF EXISTS {$wpdb->prefix}fvm_logs");
|
375 |
|
376 |
+
# process cache settings
|
377 |
+
fvm_purge_static_files();
|
|
|
|
|
378 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
379 |
}
|
380 |
|
381 |
|
inc/common.php
CHANGED
@@ -74,7 +74,7 @@ function fvm_process_cache_purge_request(){
|
|
74 |
if($_GET['fvm_do'] == 'clear_all') {
|
75 |
|
76 |
# purge everything
|
77 |
-
$cache =
|
78 |
$others = fvm_purge_others();
|
79 |
|
80 |
if(is_admin()) {
|
@@ -100,163 +100,13 @@ function fvm_process_cache_purge_request(){
|
|
100 |
}
|
101 |
|
102 |
|
103 |
-
# get cache directories and urls
|
104 |
-
function fvm_cachepath() {
|
105 |
-
|
106 |
-
# must have
|
107 |
-
if(!defined('WP_CONTENT_DIR')) { return false; }
|
108 |
-
if(!defined('WP_CONTENT_URL')) { return false; }
|
109 |
-
|
110 |
-
# to var
|
111 |
-
$wp_content_dir = WP_CONTENT_DIR;
|
112 |
-
$wp_content_url = WP_CONTENT_URL;
|
113 |
-
|
114 |
-
# globals
|
115 |
-
global $fvm_settings;
|
116 |
-
|
117 |
-
# force https option
|
118 |
-
if(isset($fvm_settings['global']['force-ssl']) && $fvm_settings['global']['force-ssl'] == true) {
|
119 |
-
$wp_content_url = str_ireplace('http:', 'https:', $wp_content_url);
|
120 |
-
}
|
121 |
-
|
122 |
-
# define cache directory
|
123 |
-
$cache_dir = $wp_content_dir . DIRECTORY_SEPARATOR . 'cache';
|
124 |
-
$cache_base_dir = $cache_dir . DIRECTORY_SEPARATOR .'fvm';
|
125 |
-
$cache_base_dirurl = $wp_content_url . '/cache/fvm';
|
126 |
-
|
127 |
-
# use alternative directory?
|
128 |
-
if(isset($fvm_settings['cache']['path']) && !empty($fvm_settings['cache']['path']) && isset($fvm_settings['cache']['url']) && !empty($fvm_settings['cache']['url']) && is_dir($fvm_settings['cache']['path'])) {
|
129 |
-
$cache_dir = rtrim($fvm_settings['cache']['path'], '/');
|
130 |
-
$cache_base_dir = $cache_dir . DIRECTORY_SEPARATOR .'fvm';
|
131 |
-
$cache_base_dirurl = rtrim($fvm_settings['cache']['url'], '/') . '/fvm';
|
132 |
-
}
|
133 |
-
|
134 |
-
# get requested hostname
|
135 |
-
$host = fvm_get_domain();
|
136 |
-
|
137 |
-
$cache_dir_min = $cache_base_dir . DIRECTORY_SEPARATOR . 'min' . DIRECTORY_SEPARATOR . $host;
|
138 |
-
$cache_url_min = $cache_base_dirurl . '/min/' .$host;
|
139 |
-
|
140 |
-
# mkdir and check if umask requires chmod, but only for hosts matching the site_url'
|
141 |
-
$dirs = array($cache_dir, $cache_base_dir, $cache_dir_min);
|
142 |
-
foreach ($dirs as $d) {
|
143 |
-
fvm_create_dir($d);
|
144 |
-
}
|
145 |
-
|
146 |
-
# return
|
147 |
-
return array(
|
148 |
-
'cache_base_dir'=>$cache_base_dir,
|
149 |
-
'cache_base_dirurl'=>$cache_base_dirurl,
|
150 |
-
'cache_dir_min'=>$cache_dir_min,
|
151 |
-
'cache_url_min'=>$cache_url_min
|
152 |
-
);
|
153 |
-
}
|
154 |
-
|
155 |
-
|
156 |
# Purge everything
|
157 |
function fvm_purge_all() {
|
158 |
-
|
159 |
fvm_purge_others();
|
160 |
return true;
|
161 |
}
|
162 |
|
163 |
-
# Purge minification only
|
164 |
-
function fvm_purge_minification() {
|
165 |
-
|
166 |
-
# flush opcache
|
167 |
-
if(function_exists('opcache_reset')) {
|
168 |
-
@opcache_reset();
|
169 |
-
}
|
170 |
-
|
171 |
-
# increment cache file names
|
172 |
-
$now = fvm_cache_increment();
|
173 |
-
|
174 |
-
# truncate cache table (doesn't work with prepared statements)
|
175 |
-
global $wpdb;
|
176 |
-
|
177 |
-
# purge cache table
|
178 |
-
$tbl_name = "{$wpdb->prefix}fvm_cache";
|
179 |
-
$wpdb->query("TRUNCATE TABLE `$tbl_name`");
|
180 |
-
|
181 |
-
# purge logs table
|
182 |
-
$tbl_name = "{$wpdb->prefix}fvm_logs";
|
183 |
-
$wpdb->query("TRUNCATE TABLE `$tbl_name`");
|
184 |
-
|
185 |
-
# get cache and min directories
|
186 |
-
global $fvm_cache_paths, $fvm_settings;
|
187 |
-
|
188 |
-
# fetch settings on wp-cli
|
189 |
-
if(is_null($fvm_settings)) { $fvm_settings = fvm_get_settings(); }
|
190 |
-
if(is_null($fvm_cache_paths)) { $fvm_cache_paths = fvm_cachepath(); }
|
191 |
-
|
192 |
-
# purge html directory?
|
193 |
-
if(isset($fvm_cache_paths['cache_dir_min']) && is_dir($fvm_cache_paths['cache_dir_min']) && is_writable($fvm_cache_paths['cache_dir_min']) && stripos($fvm_cache_paths['cache_dir_min'], DIRECTORY_SEPARATOR . 'fvm') !== false) {
|
194 |
-
|
195 |
-
# purge css/js files instantly
|
196 |
-
if(isset($fvm_settings['cache']['min_instant_purge']) && $fvm_settings['cache']['min_instant_purge'] == true) {
|
197 |
-
$result = fvm_purge_minification_now();
|
198 |
-
return $result;
|
199 |
-
} else {
|
200 |
-
# schedule purge for 24 hours later, only once
|
201 |
-
add_action( 'fvm_purge_minification_later', 'fvm_purge_minification_expired' );
|
202 |
-
wp_schedule_single_event(time() + 3600 * 24, 'fvm_purge_minification_later');
|
203 |
-
return __( 'Expired minification files are set to be deleted in 24 hours.', 'fast-velocity-minify' );
|
204 |
-
}
|
205 |
-
|
206 |
-
} else {
|
207 |
-
return __( 'The cache directory is not writeable!', 'fast-velocity-minify' );
|
208 |
-
}
|
209 |
-
|
210 |
-
return false;
|
211 |
-
}
|
212 |
-
|
213 |
-
|
214 |
-
# purge minified files right now
|
215 |
-
function fvm_purge_minification_now() {
|
216 |
-
global $fvm_cache_paths;
|
217 |
-
if(isset($fvm_cache_paths['cache_dir_min']) && stripos($fvm_cache_paths['cache_dir_min'], DIRECTORY_SEPARATOR . 'fvm') !== false) {
|
218 |
-
$result = fvm_rrmdir($fvm_cache_paths['cache_dir_min']);
|
219 |
-
return $result;
|
220 |
-
} else {
|
221 |
-
return __( 'The cache directory is not writeable!', 'fast-velocity-minify' );
|
222 |
-
}
|
223 |
-
}
|
224 |
-
|
225 |
-
# purge expired minification files only
|
226 |
-
function fvm_purge_minification_expired() {
|
227 |
-
global $fvm_cache_paths;
|
228 |
-
if(isset($fvm_cache_paths['cache_dir_min']) && !empty($fvm_cache_paths['cache_dir_min']) && stripos($fvm_cache_paths['cache_dir_min'], DIRECTORY_SEPARATOR . 'fvm') !== false) {
|
229 |
-
|
230 |
-
# must be on the allowed path
|
231 |
-
$wd = $fvm_cache_paths['cache_dir_min'];
|
232 |
-
if(empty($wd) || !defined('WP_CONTENT_DIR') || stripos($wd, DIRECTORY_SEPARATOR . 'fvm') === false) {
|
233 |
-
return __( 'Requested purge path is not allowed!', 'fast-velocity-minify' );
|
234 |
-
}
|
235 |
-
|
236 |
-
# prefix
|
237 |
-
$skip = get_option('fvm_last_cache_update', '0');
|
238 |
-
|
239 |
-
# purge only the expired cache that doesn't match the current cache version prefix and it's older than 24 hours
|
240 |
-
clearstatcache();
|
241 |
-
if(is_dir($wd)) {
|
242 |
-
try {
|
243 |
-
$i = new DirectoryIterator($wd);
|
244 |
-
foreach($i as $f){
|
245 |
-
if($f->isFile() && stripos(basename($f->getRealPath()), $skip) === false){
|
246 |
-
if($f->getMTime() <= time() - 86400) {
|
247 |
-
@unlink($f->getRealPath());
|
248 |
-
}
|
249 |
-
}
|
250 |
-
}
|
251 |
-
} catch (Exception $e) {
|
252 |
-
return get_class($e) . ": " . $e->getMessage();
|
253 |
-
}
|
254 |
-
}
|
255 |
-
|
256 |
-
return __( 'Expired cache is now deleted!', 'fast-velocity-minify' );
|
257 |
-
}
|
258 |
-
}
|
259 |
-
|
260 |
|
261 |
# purge supported hosting and plugins
|
262 |
function fvm_purge_others(){
|
@@ -299,11 +149,17 @@ function fvm_purge_others(){
|
|
299 |
return __( 'All caches on <strong>Comet Cache</strong> have been purged.', 'fast-velocity-minify' );
|
300 |
}
|
301 |
|
302 |
-
# Purge LiteSpeed Cache
|
303 |
-
if (
|
304 |
-
|
305 |
return __( 'All caches on <strong>LiteSpeed Cache</strong> have been purged.', 'fast-velocity-minify' );
|
306 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
307 |
|
308 |
# Purge Hyper Cache
|
309 |
if (class_exists( 'HyperCache' )) {
|
@@ -425,149 +281,164 @@ function fvm_godaddy_request( $method, $url = null ) {
|
|
425 |
}
|
426 |
|
427 |
|
|
|
428 |
# check if we can minify the page
|
429 |
-
function
|
|
|
|
|
|
|
|
|
430 |
|
431 |
-
|
|
|
432 |
|
433 |
-
#
|
434 |
-
|
435 |
-
return false;
|
436 |
-
}
|
437 |
|
438 |
-
#
|
439 |
-
|
|
|
|
|
|
|
440 |
return false;
|
441 |
}
|
442 |
|
443 |
-
#
|
444 |
-
|
445 |
|
446 |
-
|
447 |
-
if(isset($parseurl["query"]) && !empty($parseurl["query"])) {
|
448 |
-
|
449 |
-
# parse query string to array
|
450 |
-
$query_string_arr = array();
|
451 |
-
parse_str($parseurl["query"], $query_string_arr);
|
452 |
-
|
453 |
-
# specifically allowed query strings
|
454 |
-
$allowed = array('_ga', 'age-verified', 'ao_noptimize', 'cn-reloaded', 'fb_action_ids', 'fb_action_types', 'fb_source', 'fbclid', 'gclid', 'usqp', 'utm_campaign', 'utm_content', 'utm_expid', 'utm_medium', 'utm_source', 'utm_term');
|
455 |
-
|
456 |
-
foreach ( $allowed as $qs) {
|
457 |
-
if(isset($query_string_arr[$qs])) { unset($query_string_arr[$qs]); }
|
458 |
-
}
|
459 |
|
460 |
-
|
461 |
-
|
462 |
-
return false;
|
463 |
-
}
|
464 |
-
}
|
465 |
-
|
466 |
-
}
|
467 |
-
|
468 |
-
# compatibility with DONOTCACHEPAGE
|
469 |
-
if( defined('DONOTCACHEPAGE') && DONOTCACHEPAGE ){ return false; }
|
470 |
|
471 |
-
#
|
472 |
-
if(
|
|
|
473 |
|
474 |
-
#
|
475 |
-
if(
|
476 |
-
if( defined('WP_INSTALLING') && WP_INSTALLING ){ return false; }
|
477 |
-
if( defined('WP_REPAIRING') && WP_REPAIRING ){ return false; }
|
478 |
-
if( defined('WP_IMPORTING') && WP_IMPORTING ){ return false; }
|
479 |
-
if( defined('DOING_AJAX') && DOING_AJAX ){ return false; }
|
480 |
-
if( defined('WP_CLI') && WP_CLI ){ return false; }
|
481 |
-
if( defined('XMLRPC_REQUEST') && XMLRPC_REQUEST ){ return false; }
|
482 |
-
if( defined('WP_ADMIN') && WP_ADMIN ){ return false; }
|
483 |
-
if( defined('SHORTINIT') && SHORTINIT ){ return false; }
|
484 |
-
if( defined('IFRAME_REQUEST') && IFRAME_REQUEST ){ return false; }
|
485 |
|
486 |
-
#
|
487 |
-
|
488 |
-
if(function_exists('is_feed') && is_feed()){ return false; }
|
489 |
-
if(function_exists('is_comment_feed') && is_comment_feed()){ return false; }
|
490 |
-
if(function_exists('is_attachment') && is_attachment()){ return false; }
|
491 |
-
if(function_exists('is_trackback') && is_trackback()){ return false; }
|
492 |
-
if(function_exists('is_robots') && is_robots()){ return false; }
|
493 |
-
if(function_exists('is_preview') && is_preview()){ return false; }
|
494 |
-
if(function_exists('is_customize_preview') && is_customize_preview()){ return false; }
|
495 |
-
if(function_exists('is_embed') && is_embed()){ return false; }
|
496 |
-
if(function_exists('is_admin') && is_admin()){ return false; }
|
497 |
-
if(function_exists('is_blog_admin') && is_blog_admin()){ return false; }
|
498 |
-
if(function_exists('is_network_admin') && is_network_admin()){ return false; }
|
499 |
|
500 |
-
#
|
501 |
-
if(
|
502 |
-
|
503 |
-
|
504 |
-
if(function_exists('is_wc_endpoint_url') && is_wc_endpoint_url()){ return false; }
|
505 |
|
506 |
-
#
|
507 |
-
|
508 |
-
|
509 |
-
|
|
|
|
|
|
|
|
|
|
|
510 |
|
511 |
-
#
|
512 |
-
|
|
|
513 |
|
514 |
-
#
|
515 |
-
if(
|
516 |
-
if($host != $fvm_urls['wp_domain']) {
|
517 |
-
return false;
|
518 |
-
}
|
519 |
-
}
|
520 |
|
521 |
-
#
|
522 |
-
$
|
523 |
-
if($ruri !== false && !empty($ruri)) {
|
524 |
|
525 |
-
|
526 |
-
|
527 |
-
|
528 |
-
if(substr($ruri, -strlen($ext)) == $ext) {
|
529 |
-
return false;
|
530 |
-
}
|
531 |
-
}
|
532 |
-
|
533 |
}
|
534 |
|
535 |
-
#
|
536 |
-
if(
|
537 |
-
|
538 |
-
|
539 |
-
# get user roles
|
540 |
-
global $fvm_settings;
|
541 |
-
$user = wp_get_current_user();
|
542 |
-
$roles = (array) $user->roles;
|
543 |
-
foreach($roles as $role) {
|
544 |
-
if(isset($fvm_settings['minify'][$role])) { return true; }
|
545 |
-
}
|
546 |
-
|
547 |
-
# disable for logged in users by default
|
548 |
-
return false;
|
549 |
-
}
|
550 |
}
|
551 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
552 |
|
|
|
|
|
553 |
|
554 |
# default
|
555 |
return true;
|
556 |
}
|
557 |
|
558 |
|
559 |
-
#
|
560 |
-
function
|
|
|
|
|
|
|
|
|
|
|
|
|
561 |
|
562 |
-
|
563 |
-
|
564 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
565 |
}
|
566 |
|
567 |
-
|
|
|
568 |
}
|
569 |
|
570 |
|
|
|
|
|
|
|
|
|
|
|
571 |
# check if PHP has some functions disabled
|
572 |
function fvm_function_available($func) {
|
573 |
if (ini_get('safe_mode')) return false;
|
@@ -605,43 +476,58 @@ function fvm_format_filesize($bytes, $decimals = 2) {
|
|
605 |
return sprintf( "%1.{$decimals}f %s", round( $bytes, $decimals ), $units[$i] );
|
606 |
}
|
607 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
608 |
|
609 |
-
#
|
610 |
-
|
611 |
-
|
612 |
-
|
613 |
-
|
614 |
-
|
615 |
-
|
616 |
-
|
617 |
-
|
618 |
-
|
619 |
-
|
620 |
-
|
621 |
-
|
622 |
-
|
623 |
-
|
624 |
-
|
625 |
-
|
626 |
-
|
627 |
-
|
628 |
-
try {
|
629 |
-
$i = new DirectoryIterator($path);
|
630 |
-
foreach($i as $f){
|
631 |
-
if($f->isFile()){ @unlink($f->getRealPath());
|
632 |
-
} else if(!$f->isDot() && $f->isDir()){
|
633 |
-
fvm_rrmdir($f->getRealPath());
|
634 |
-
if(is_dir($f->getRealPath())) { @rmdir($f->getRealPath()); }
|
635 |
}
|
|
|
636 |
}
|
637 |
-
|
638 |
-
return get_class($e) . ": " . $e->getMessage();
|
639 |
}
|
640 |
-
|
641 |
-
# self
|
642 |
-
if(is_dir($path)) { @rmdir($path); }
|
643 |
}
|
644 |
-
|
645 |
}
|
646 |
|
647 |
|
@@ -732,10 +618,6 @@ function fvm_get_default_settings($fvm_settings) {
|
|
732 |
# css
|
733 |
$fvm_settings['css']['enable'] = 1;
|
734 |
$fvm_settings['css']['noprint'] = 1;
|
735 |
-
|
736 |
-
# cdn
|
737 |
-
$arr = array('img[src*=/wp-content/], img[data-src*=/wp-content/], img[data-srcset*=/wp-content/]', 'picture source[srcset*=/wp-content/]', 'video source[type*=video]', 'image[height]', 'link[rel=icon], link[rel=apple-touch-icon]', 'meta[name=msapplication-TileImage]', 'a[data-interchange*=/wp-content/]', 'rs-slide[data-thumb]', 'form[data-product_variations]', 'div[data-background-image], section[data-background-image]');
|
738 |
-
$fvm_settings['cdn']['integration'] = implode(PHP_EOL, fvm_array_order($arr));
|
739 |
|
740 |
}
|
741 |
|
@@ -846,9 +728,6 @@ function fvm_get_updated_field_routines($fvm_settings) {
|
|
846 |
|
847 |
}
|
848 |
|
849 |
-
# clear old cron
|
850 |
-
wp_clear_scheduled_hook( 'fastvelocity_purge_old_cron_event' );
|
851 |
-
|
852 |
# mark as done
|
853 |
update_option('fastvelocity_upgraded', true);
|
854 |
|
@@ -861,174 +740,541 @@ function fvm_get_updated_field_routines($fvm_settings) {
|
|
861 |
}
|
862 |
|
863 |
# save log to database
|
|
|
864 |
function fvm_save_log($arr) {
|
865 |
|
866 |
# must have
|
867 |
-
if(
|
868 |
-
if(!isset($arr['uid']) || !isset($arr['date']) || !isset($arr['type']) || !isset($arr['content']) || !isset($arr['meta'])) { return false; }
|
869 |
|
870 |
-
#
|
871 |
-
if(
|
872 |
-
|
873 |
-
|
874 |
-
|
|
|
|
|
875 |
|
876 |
# initialize arrays (fields, types, values)
|
877 |
$fld = array();
|
878 |
$tpe = array();
|
879 |
$vls = array();
|
880 |
-
|
881 |
-
# define possible
|
882 |
-
$
|
883 |
-
$int = array('date');
|
884 |
-
$all = array_merge($str, $int);
|
885 |
|
886 |
# process only recognized columns
|
887 |
foreach($arr as $k=>$v) {
|
888 |
if(in_array($k, $all)) {
|
889 |
-
|
890 |
-
if($k == 'content') { $v = json_encode($v); }
|
891 |
-
if($k == 'meta') { $v = json_encode($v); }
|
892 |
-
if($k == 'uid') { $v = hash('sha1', $v); }
|
893 |
-
|
894 |
-
# array for prepare
|
895 |
$fld[] = $k;
|
896 |
$vls[] = $v;
|
897 |
}
|
898 |
}
|
899 |
|
900 |
-
|
901 |
-
|
902 |
-
|
903 |
-
|
904 |
-
|
905 |
-
|
906 |
-
|
907 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
908 |
}
|
909 |
-
|
910 |
# fallback
|
911 |
return false;
|
912 |
|
913 |
}
|
914 |
|
915 |
|
|
|
|
|
|
|
|
|
916 |
|
917 |
|
918 |
-
#
|
919 |
-
function
|
920 |
-
|
921 |
-
# must have
|
922 |
-
if(is_null($url) || empty($url)) {
|
923 |
-
return array('error'=> __( 'Invalid URL', 'fast-velocity-minify' ));
|
924 |
-
}
|
925 |
-
|
926 |
-
# get domain
|
927 |
-
global $fvm_urls;
|
928 |
|
929 |
-
#
|
930 |
-
|
931 |
-
|
932 |
-
# file path + windows compatibility
|
933 |
-
$f = str_replace('/', DIRECTORY_SEPARATOR, str_replace(rtrim($fvm_urls['wp_site_url'], '/'), ABSPATH, $url));
|
934 |
-
|
935 |
-
# did it work?
|
936 |
-
if (file_exists($f)) {
|
937 |
-
|
938 |
-
# check contents
|
939 |
-
$code = file_get_contents($f);
|
940 |
-
if(fvm_not_php_html($code)) {
|
941 |
-
return array('content'=>$code, 'src'=>'Disk');
|
942 |
-
}
|
943 |
-
}
|
944 |
-
}
|
945 |
|
946 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
947 |
|
948 |
-
#
|
949 |
-
|
|
|
|
|
|
|
950 |
|
951 |
-
|
952 |
-
|
953 |
-
|
954 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
955 |
}
|
956 |
|
957 |
-
#
|
958 |
-
|
959 |
-
$
|
960 |
-
|
|
|
|
|
|
|
|
|
961 |
|
962 |
-
|
963 |
-
|
|
|
|
|
|
|
|
|
|
|
964 |
|
965 |
-
#
|
966 |
-
$
|
967 |
-
|
968 |
-
|
969 |
-
|
970 |
-
|
971 |
-
|
972 |
-
|
973 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
974 |
}
|
975 |
}
|
976 |
|
977 |
-
|
978 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
979 |
}
|
980 |
|
981 |
|
982 |
-
#
|
983 |
-
function
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
984 |
|
985 |
-
|
986 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
987 |
|
988 |
-
|
989 |
-
|
990 |
-
|
991 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
992 |
|
993 |
-
|
994 |
-
|
995 |
|
996 |
-
|
997 |
-
|
998 |
-
fvm_fix_permission_bits($file);
|
999 |
-
return true;
|
1000 |
|
|
|
|
|
|
|
|
|
|
|
|
|
1001 |
}
|
1002 |
|
1003 |
|
1004 |
-
|
1005 |
-
|
|
|
1006 |
|
1007 |
-
#
|
1008 |
-
global $
|
1009 |
-
$tbl_name = "{$wpdb->prefix}fvm_cache";
|
1010 |
|
1011 |
-
#
|
1012 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1013 |
|
1014 |
-
# check or fetch
|
1015 |
-
if($check) {
|
1016 |
-
$sql = $wpdb->prepare("SELECT id FROM `$tbl_name` WHERE uid = '%s' LIMIT 1", $key);
|
1017 |
} else {
|
1018 |
-
|
|
|
1019 |
}
|
|
|
|
|
|
|
|
|
|
|
1020 |
|
1021 |
-
|
1022 |
-
|
|
|
1023 |
|
1024 |
-
#
|
1025 |
-
|
1026 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1027 |
}
|
1028 |
|
1029 |
-
#
|
1030 |
-
|
1031 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1032 |
}
|
1033 |
|
1034 |
# fallback
|
@@ -1040,17 +1286,19 @@ function fvm_set_transient($arr) {
|
|
1040 |
|
1041 |
# must have
|
1042 |
if(!is_array($arr) || (is_array($arr) && (count($arr) == 0 || empty($arr)))) { return false; }
|
1043 |
-
if(!isset($arr['uid']) || !isset($arr['date']) || !isset($arr['type']) || !isset($arr['content'])
|
1044 |
|
1045 |
# normalize unknown keys
|
1046 |
-
if(strlen($arr['uid']) !=
|
1047 |
|
1048 |
-
# check if it already exists
|
1049 |
$status = fvm_get_transient($arr['uid'], true);
|
1050 |
-
if($status) { return
|
1051 |
-
|
1052 |
-
#
|
1053 |
global $wpdb;
|
|
|
|
|
1054 |
|
1055 |
# initialize arrays (fields, types, values)
|
1056 |
$fld = array();
|
@@ -1066,22 +1314,23 @@ function fvm_set_transient($arr) {
|
|
1066 |
foreach($arr as $k=>$v) {
|
1067 |
if(in_array($k, $all)) {
|
1068 |
if(in_array($k, $str)) { $tpe[] = '%s'; } else { $tpe[] = '%d'; }
|
1069 |
-
if($k == 'meta') { $v = json_encode($v); }
|
1070 |
$fld[] = $k;
|
1071 |
$vls[] = $v;
|
1072 |
}
|
1073 |
}
|
1074 |
-
|
1075 |
-
# prepare and insert to database
|
1076 |
-
$tbl_name = "{$wpdb->prefix}fvm_cache";
|
1077 |
-
$sql = $wpdb->prepare("INSERT IGNORE INTO `$tbl_name` (".implode(', ', $fld).") VALUES (".implode(', ', $tpe).")", $vls);
|
1078 |
-
$result = $wpdb->query($sql);
|
1079 |
|
1080 |
-
|
1081 |
-
|
1082 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1083 |
}
|
1084 |
-
|
1085 |
# fallback
|
1086 |
return false;
|
1087 |
|
@@ -1090,74 +1339,74 @@ function fvm_set_transient($arr) {
|
|
1090 |
# delete transient
|
1091 |
function fvm_del_transient($key) {
|
1092 |
|
1093 |
-
global $wpdb;
|
1094 |
-
|
1095 |
# normalize unknown keys
|
1096 |
-
if(strlen($key) !=
|
1097 |
|
1098 |
-
#
|
1099 |
-
|
1100 |
-
$
|
1101 |
-
$
|
1102 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1103 |
}
|
1104 |
|
1105 |
|
1106 |
# functions, get full url
|
1107 |
-
function fvm_normalize_url($
|
1108 |
|
1109 |
# preserve empty source handles
|
1110 |
-
$
|
|
|
1111 |
|
1112 |
# some fixes
|
1113 |
-
$
|
1114 |
-
|
1115 |
-
#make sure wp_home doesn't have a forward slash
|
1116 |
-
$wp_home = rtrim($wp_home, '/');
|
1117 |
|
1118 |
-
#
|
1119 |
-
$
|
1120 |
-
|
1121 |
-
|
1122 |
-
|
1123 |
-
|
1124 |
-
|
1125 |
-
|
1126 |
-
|
1127 |
-
|
1128 |
-
|
1129 |
-
|
1130 |
-
$
|
1131 |
-
|
1132 |
-
|
1133 |
-
|
1134 |
-
|
1135 |
-
|
1136 |
-
|
1137 |
-
if (substr($
|
1138 |
-
$
|
|
|
|
|
|
|
|
|
1139 |
}
|
1140 |
|
1141 |
-
#
|
1142 |
-
$
|
1143 |
-
|
1144 |
-
# no query strings on css and js files
|
1145 |
-
if (stripos($hurl, '.js?') !== false) { $hurl = stristr($hurl, '.js?', true).'.js'; } # no query strings
|
1146 |
-
if (stripos($hurl, '.css?') !== false) { $hurl = stristr($hurl, '.css?', true).'.css'; } # no query strings
|
1147 |
-
|
1148 |
-
# add filter for developers
|
1149 |
-
$hurl = apply_filters('fvm_get_url', $hurl);
|
1150 |
|
1151 |
-
return $
|
1152 |
}
|
1153 |
|
1154 |
|
1155 |
# minify ld+json scripts
|
1156 |
function fvm_minify_microdata($data) {
|
1157 |
-
# remove // comments
|
1158 |
$data = trim(preg_replace('/(\v)+(\h)+[\/]{2}(.*)+(\v)+/u', '', $data));
|
1159 |
-
|
1160 |
-
# minify
|
1161 |
$data = trim(preg_replace('/\s+/u', ' ', $data));
|
1162 |
$data = str_replace(array('" ', ' "'), '"', $data);
|
1163 |
$data = str_replace(array('[ ', ' ['), '[', $data);
|
@@ -1188,7 +1437,7 @@ function fvm_not_php_html($code) {
|
|
1188 |
|
1189 |
# find if a string looks like HTML content
|
1190 |
function fvm_is_html($html) {
|
1191 |
-
|
1192 |
# return early if it's html
|
1193 |
$html = trim($html);
|
1194 |
$a = '<!doctype';
|
@@ -1232,16 +1481,6 @@ function fvm_is_html($html) {
|
|
1232 |
|
1233 |
}
|
1234 |
|
1235 |
-
|
1236 |
-
# remove UTF8 BOM
|
1237 |
-
function fvm_remove_utf8_bom($text) {
|
1238 |
-
$bom = pack('H*','EFBBBF');
|
1239 |
-
while (preg_match("/^$bom/", $text)) {
|
1240 |
-
$text = preg_replace("/^$bom/ui", '', $text);
|
1241 |
-
}
|
1242 |
-
return $text;
|
1243 |
-
}
|
1244 |
-
|
1245 |
# ensure that string is utf8
|
1246 |
function fvm_ensure_utf8($str) {
|
1247 |
$enc = mb_detect_encoding($str, mb_list_encodings(), true);
|
@@ -1258,20 +1497,175 @@ function fvm_ensure_utf8($str) {
|
|
1258 |
}
|
1259 |
|
1260 |
|
1261 |
-
#
|
1262 |
-
function
|
|
|
1263 |
|
1264 |
-
#
|
1265 |
-
$
|
|
|
|
|
1266 |
|
1267 |
-
#
|
1268 |
-
if(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1269 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1270 |
# process css only if it's not php or html
|
1271 |
if(fvm_not_php_html($css)) {
|
1272 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1273 |
# filtering
|
1274 |
-
$css =
|
1275 |
$css = str_ireplace('@charset "UTF-8";', '', $css);
|
1276 |
|
1277 |
# remove query strings from fonts
|
@@ -1287,32 +1681,27 @@ function fvm_maybe_minify_css_file($css, $url, $min) {
|
|
1287 |
$css = preg_replace("/url\(\s*['\"]?(?!data:)(?!http)(?![\/'\"#])(.+?)['\"]?\s*\)/ui", "url(".dirname($url)."/$1)", $css);
|
1288 |
}
|
1289 |
|
1290 |
-
|
1291 |
-
|
1292 |
# minify string with relative urls
|
1293 |
-
if($min) {
|
1294 |
-
$css = fvm_minify_css_string($css);
|
1295 |
}
|
1296 |
|
1297 |
# add font-display block for all font faces
|
1298 |
# https://developers.google.com/web/updates/2016/02/font-display
|
1299 |
-
$
|
1300 |
-
|
1301 |
-
|
1302 |
-
|
1303 |
-
|
1304 |
-
|
1305 |
-
if(isset($mff2[1]) && is_array($mff2[1]) && isset($mff2[1][0])) {
|
1306 |
-
if(stripos($mff2[1][0], 'font-display:') === false) {
|
1307 |
-
$css = str_replace($mff2[1][0], 'font-display:block;'.$mff2[1][0], $css);
|
1308 |
-
}
|
1309 |
}
|
1310 |
-
|
1311 |
-
|
|
|
|
|
1312 |
|
1313 |
# make relative urls when possible
|
1314 |
-
|
1315 |
-
|
1316 |
# get root url, preserve subdirectories
|
1317 |
if(isset($fvm_urls['wp_site_url']) && !empty($fvm_urls['wp_site_url'])) {
|
1318 |
|
@@ -1325,18 +1714,44 @@ function fvm_maybe_minify_css_file($css, $url, $min) {
|
|
1325 |
|
1326 |
# adjust paths
|
1327 |
$bgimgs = array();
|
1328 |
-
preg_match_all ('/url\s*\((\s*[\'"]?(http
|
1329 |
if(isset($bgimgs[1]) && is_array($bgimgs[1])) {
|
1330 |
foreach($bgimgs[1] as $img) {
|
|
|
|
|
|
|
|
|
|
|
|
|
1331 |
if(substr($img, 0, strlen($use_url)) == $use_url) {
|
1332 |
$pos = strpos($img, $use_url);
|
1333 |
if ($pos !== false) {
|
1334 |
-
|
|
|
|
|
|
|
|
|
1335 |
$css = str_replace($img, $relimg, $css);
|
|
|
1336 |
}
|
1337 |
}
|
1338 |
}
|
1339 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1340 |
}
|
1341 |
|
1342 |
# return css
|
@@ -1344,7 +1759,7 @@ function fvm_maybe_minify_css_file($css, $url, $min) {
|
|
1344 |
|
1345 |
}
|
1346 |
|
1347 |
-
return false;
|
1348 |
}
|
1349 |
|
1350 |
|
@@ -1364,7 +1779,7 @@ function fvm_maybe_minify_js($js, $url, $enable_js_minification) {
|
|
1364 |
global $fvm_settings;
|
1365 |
|
1366 |
# filtering
|
1367 |
-
$js =
|
1368 |
|
1369 |
# remove sourceMappingURL
|
1370 |
$js = preg_replace('/(\/\/\s*[#]\s*sourceMappingURL\s*[=]\s*)([a-zA-Z0-9-_\.\/]+)(\.map)/ui', '', $js);
|
@@ -1421,8 +1836,8 @@ function fvm_escape_url_js($str) {
|
|
1421 |
|
1422 |
# try catch wrapper for merged javascript
|
1423 |
function fvm_try_catch_wrap($js, $href=null) {
|
1424 |
-
$loc = ''; if(isset($href)) { $loc = '[
|
1425 |
-
return
|
1426 |
}
|
1427 |
|
1428 |
|
@@ -1490,99 +1905,40 @@ function fvm_rewrite_assets_cdn($html) {
|
|
1490 |
}
|
1491 |
|
1492 |
|
1493 |
-
|
1494 |
-
|
1495 |
-
function fvm_replace_css_imports($css, $rq=null) {
|
1496 |
|
1497 |
-
#
|
1498 |
-
|
1499 |
-
|
1500 |
-
#
|
1501 |
-
$
|
1502 |
-
|
1503 |
-
if
|
1504 |
-
|
1505 |
-
|
1506 |
-
|
1507 |
-
|
1508 |
-
$url = trim($cssimports[2][$k]);
|
1509 |
-
} else {
|
1510 |
-
if(!is_null($rq) && !empty($rq)) {
|
1511 |
-
$url = dirname($rq) . '/' . trim($cssimports[2][$k]);
|
1512 |
-
}
|
1513 |
-
}
|
1514 |
|
1515 |
-
|
1516 |
-
|
1517 |
-
|
1518 |
-
# make sure we have a complete url
|
1519 |
-
$href = fvm_normalize_url($url, $fvm_urls['wp_domain'], $fvm_urls['wp_site_url']);
|
1520 |
-
|
1521 |
-
# download, minify, cache (no ver query string)
|
1522 |
-
$tkey = hash('sha1', $href);
|
1523 |
-
$subcss = fvm_get_transient($tkey);
|
1524 |
-
if ($subcss === false) {
|
1525 |
-
|
1526 |
-
# get minification settings for files
|
1527 |
-
if(isset($fvm_settings['css']['min_files'])) {
|
1528 |
-
$enable_css_minification = $fvm_settings['css']['min_files'];
|
1529 |
-
}
|
1530 |
-
|
1531 |
-
# force minification on google fonts
|
1532 |
-
if(stripos($href, 'fonts.googleapis.com') !== false) {
|
1533 |
-
$enable_css_minification = true;
|
1534 |
-
}
|
1535 |
-
|
1536 |
-
# download file, get contents, merge
|
1537 |
-
$ddl = fvm_maybe_download($href);
|
1538 |
-
|
1539 |
-
# if success
|
1540 |
-
if(isset($ddl['content'])) {
|
1541 |
-
|
1542 |
-
# contents
|
1543 |
-
$subcss = $ddl['content'];
|
1544 |
-
|
1545 |
-
# minify
|
1546 |
-
$subcss = fvm_maybe_minify_css_file($subcss, $href, $enable_css_minification);
|
1547 |
-
|
1548 |
-
# developers filter
|
1549 |
-
$subcss = apply_filters( 'fvm_after_download_and_minify_code', $subcss, 'css');
|
1550 |
-
|
1551 |
-
# remove specific, minified CSS code
|
1552 |
-
if(isset($fvm_settings['css']['remove_code']) && !empty($fvm_settings['css']['remove_code'])) {
|
1553 |
-
$arr = fvm_string_toarray($fvm_settings['css']['remove_code']);
|
1554 |
-
if(is_array($arr) && count($arr) > 0) {
|
1555 |
-
foreach($arr as $str) {
|
1556 |
-
$subcss = str_replace($str, '', $subcss);
|
1557 |
-
}
|
1558 |
-
}
|
1559 |
-
}
|
1560 |
-
|
1561 |
-
# trim code
|
1562 |
-
$subcss = trim($subcss);
|
1563 |
-
|
1564 |
-
# size in bytes
|
1565 |
-
$fs = strlen($subcss);
|
1566 |
-
$ur = str_replace($fvm_urls['wp_site_url'], '', $href);
|
1567 |
-
$tkey_meta = array('fs'=>$fs, 'url'=>str_replace($fvm_cache_paths['cache_url_min'].'/', '', $ur), 'mt'=>$media);
|
1568 |
-
|
1569 |
-
# save
|
1570 |
-
fvm_set_transient(array('uid'=>$tkey, 'date'=>$tvers, 'type'=>'css', 'content'=>$subcss, 'meta'=>$tkey_meta));
|
1571 |
-
}
|
1572 |
-
}
|
1573 |
-
|
1574 |
-
# replace import rule with inline code
|
1575 |
-
if ($subcss !== false && !empty($subcss)) {
|
1576 |
-
$css = str_replace($cssimport, $subcss, $css);
|
1577 |
-
}
|
1578 |
-
|
1579 |
-
}
|
1580 |
}
|
1581 |
}
|
|
|
|
|
1582 |
|
1583 |
-
#
|
1584 |
-
|
1585 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1586 |
}
|
1587 |
|
1588 |
|
@@ -1603,25 +1959,59 @@ function fvm_add_header_function($html) {
|
|
1603 |
return $html;
|
1604 |
}
|
1605 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1606 |
|
1607 |
# get the domain name
|
1608 |
function fvm_get_domain() {
|
1609 |
-
if(
|
|
|
|
|
|
|
1610 |
return $_SERVER['SERVER_NAME'];
|
1611 |
} elseif (isset($_SERVER['HTTP_HOST']) && !empty($_SERVER['HTTP_HOST'])) {
|
1612 |
return $_SERVER['HTTP_HOST'];
|
1613 |
-
} elseif (function_exists('site_url')) {
|
1614 |
-
return parse_url(site_url())['host'];
|
1615 |
} else {
|
1616 |
return false;
|
1617 |
}
|
1618 |
}
|
1619 |
|
1620 |
-
|
1621 |
# get the settings file path, current domain name, and uri path without query strings
|
1622 |
-
function fvm_get_uripath() {
|
1623 |
if (isset($_SERVER['REQUEST_URI']) && !empty($_SERVER['REQUEST_URI'])) {
|
1624 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1625 |
$current_uri = str_replace('//', '/', str_replace('..', '', preg_replace( '/[ <>\'\"\r\n\t\(\)]/', '', $current_uri)));
|
1626 |
return $current_uri;
|
1627 |
} else {
|
74 |
if($_GET['fvm_do'] == 'clear_all') {
|
75 |
|
76 |
# purge everything
|
77 |
+
$cache = fvm_purge_static_files();
|
78 |
$others = fvm_purge_others();
|
79 |
|
80 |
if(is_admin()) {
|
100 |
}
|
101 |
|
102 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
103 |
# Purge everything
|
104 |
function fvm_purge_all() {
|
105 |
+
fvm_purge_static_files();
|
106 |
fvm_purge_others();
|
107 |
return true;
|
108 |
}
|
109 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
110 |
|
111 |
# purge supported hosting and plugins
|
112 |
function fvm_purge_others(){
|
149 |
return __( 'All caches on <strong>Comet Cache</strong> have been purged.', 'fast-velocity-minify' );
|
150 |
}
|
151 |
|
152 |
+
# Purge LiteSpeed Cache
|
153 |
+
if ( has_action('litespeed_purge_all') ) {
|
154 |
+
do_action('litespeed_purge_all');
|
155 |
return __( 'All caches on <strong>LiteSpeed Cache</strong> have been purged.', 'fast-velocity-minify' );
|
156 |
}
|
157 |
+
|
158 |
+
# Purge WP Cloudflare Super Page Cache
|
159 |
+
if( class_exists('SW_CLOUDFLARE_PAGECACHE') ) {
|
160 |
+
do_action("swcfpc_purge_everything");
|
161 |
+
return __( 'All caches on <strong>WP Cloudflare Super Page Cache</strong> have been purged.', 'fast-velocity-minify' );
|
162 |
+
}
|
163 |
|
164 |
# Purge Hyper Cache
|
165 |
if (class_exists( 'HyperCache' )) {
|
281 |
}
|
282 |
|
283 |
|
284 |
+
|
285 |
# check if we can minify the page
|
286 |
+
function fvm_can_minify_js() {
|
287 |
+
|
288 |
+
# check if we hit any exclusions from the compatibility page
|
289 |
+
if(!fvm_can_process_common()) { return false; }
|
290 |
+
if(fvm_is_amp_page() === true) { return false; }
|
291 |
|
292 |
+
# url exclusions
|
293 |
+
if(!fvm_can_process_query_string('js')) { return false; }
|
294 |
|
295 |
+
# check if user role is allowed
|
296 |
+
if(!fvm_user_role_processing_allowed('js')) { return false; }
|
|
|
|
|
297 |
|
298 |
+
# settings
|
299 |
+
global $fvm_settings;
|
300 |
+
|
301 |
+
# disabled?
|
302 |
+
if(!isset($fvm_settings['js']['enable']) || (isset($fvm_settings['js']['enable']) && $fvm_settings['js']['enable'] != true)) {
|
303 |
return false;
|
304 |
}
|
305 |
|
306 |
+
# default
|
307 |
+
return true;
|
308 |
|
309 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
310 |
|
311 |
+
# check if we can minify the page
|
312 |
+
function fvm_can_process_html() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
313 |
|
314 |
+
# check if we hit any exclusions from the compatibility page
|
315 |
+
if(!fvm_can_process_common()) { return false; }
|
316 |
+
if(fvm_is_amp_page() === true) { return false; }
|
317 |
|
318 |
+
# url exclusions
|
319 |
+
if(!fvm_can_process_query_string('html')) { return false; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
320 |
|
321 |
+
# settings
|
322 |
+
global $fvm_settings;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
323 |
|
324 |
+
# disabled?
|
325 |
+
if(!isset($fvm_settings['html']['enable']) || (isset($fvm_settings['html']['enable']) && $fvm_settings['html']['enable'] != true)) {
|
326 |
+
return false;
|
327 |
+
}
|
|
|
328 |
|
329 |
+
# check if user role is allowed
|
330 |
+
if(!fvm_user_role_processing_allowed('html')) { return false; }
|
331 |
+
|
332 |
+
# default
|
333 |
+
return true;
|
334 |
+
}
|
335 |
+
|
336 |
+
# check if we can minify the page
|
337 |
+
function fvm_can_process_cdn() {
|
338 |
|
339 |
+
# check if we hit any exclusions from the compatibility page
|
340 |
+
if(!fvm_can_process_common()) { return false; }
|
341 |
+
if(fvm_is_amp_page() === true) { return false; }
|
342 |
|
343 |
+
# url exclusions
|
344 |
+
if(!fvm_can_process_query_string('cdn')) { return false; }
|
|
|
|
|
|
|
|
|
345 |
|
346 |
+
# settings
|
347 |
+
global $fvm_settings;
|
|
|
348 |
|
349 |
+
# disabled?
|
350 |
+
if(!isset($fvm_settings['cdn']['enable']) || (isset($fvm_settings['cdn']['enable']) && $fvm_settings['cdn']['enable'] != true)) {
|
351 |
+
return false;
|
|
|
|
|
|
|
|
|
|
|
352 |
}
|
353 |
|
354 |
+
# no domain
|
355 |
+
if(!isset($fvm_settings['cdn']['domain']) || (isset($fvm_settings['cdn']['domain']) && empty($fvm_settings['cdn']['domain']))) {
|
356 |
+
return false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
357 |
}
|
358 |
|
359 |
+
# check if user role is allowed
|
360 |
+
if(!fvm_user_role_processing_allowed('cdn')) { return false; }
|
361 |
+
|
362 |
+
# default
|
363 |
+
return true;
|
364 |
+
}
|
365 |
+
|
366 |
+
|
367 |
+
# check if we can minify the page
|
368 |
+
function fvm_can_minify_css() {
|
369 |
+
|
370 |
+
# check if we hit any exclusions from the compatibility page
|
371 |
+
if(!fvm_can_process_common()) { return false; }
|
372 |
+
if(fvm_is_amp_page() === true) { return false; }
|
373 |
+
|
374 |
+
# url exclusions
|
375 |
+
if(!fvm_can_process_query_string('css')) { return false; }
|
376 |
+
|
377 |
+
# check if user role is allowed
|
378 |
+
if(!fvm_user_role_processing_allowed('css')) { return false; }
|
379 |
+
|
380 |
+
# settings
|
381 |
+
global $fvm_settings;
|
382 |
|
383 |
+
# disabled?
|
384 |
+
if(!isset($fvm_settings['css']['enable']) || (isset($fvm_settings['css']['enable']) && $fvm_settings['css']['enable'] != true)) { return false; }
|
385 |
|
386 |
# default
|
387 |
return true;
|
388 |
}
|
389 |
|
390 |
|
391 |
+
# save minified code, if not yet available
|
392 |
+
function fvm_generate_min_url($url, $tkey, $type, $code) {
|
393 |
+
|
394 |
+
# files first, but only for js/css types
|
395 |
+
if(function_exists('wp_upload_dir')) {
|
396 |
+
|
397 |
+
# parse uripath and check if it matches against our rewrite format
|
398 |
+
$filename = $tkey .'.'. $type;
|
399 |
|
400 |
+
# set cache on the uploads directory
|
401 |
+
$upload_dir = wp_upload_dir();
|
402 |
+
if(isset($upload_dir['basedir']) && isset($upload_dir['baseurl']) && !empty($upload_dir['basedir'])) {
|
403 |
+
|
404 |
+
# define and create directory
|
405 |
+
$cache_dir = $upload_dir['basedir'] . DIRECTORY_SEPARATOR . 'fvm-cache'. DIRECTORY_SEPARATOR . 'min';
|
406 |
+
$cache_dir_url = $upload_dir['baseurl'] . '/fvm-cache/min';
|
407 |
+
if(!is_dir($cache_dir) && function_exists('wp_mkdir_p')) { wp_mkdir_p($cache_dir); }
|
408 |
+
|
409 |
+
# filename
|
410 |
+
$file = $cache_dir . DIRECTORY_SEPARATOR . $filename;
|
411 |
+
$public = $cache_dir_url . '/' .$filename;
|
412 |
+
|
413 |
+
# cache date
|
414 |
+
$tvers = get_option('fvm_last_cache_update', '0');
|
415 |
+
|
416 |
+
# wordpress functions
|
417 |
+
require_once (ABSPATH . DIRECTORY_SEPARATOR . 'wp-admin'. DIRECTORY_SEPARATOR .'includes'. DIRECTORY_SEPARATOR .'class-wp-filesystem-base.php');
|
418 |
+
require_once (ABSPATH . DIRECTORY_SEPARATOR .'wp-admin'. DIRECTORY_SEPARATOR .'includes'. DIRECTORY_SEPARATOR .'class-wp-filesystem-direct.php');
|
419 |
+
|
420 |
+
# create if doesn't exist
|
421 |
+
$fileSystemDirect = new WP_Filesystem_Direct(false);
|
422 |
+
if(!$fileSystemDirect->exists($file) || ($fileSystemDirect->exists($file) && $fileSystemDirect->mtime($file) < $tvers)) {
|
423 |
+
$fileSystemDirect->put_contents($file, $code);
|
424 |
+
}
|
425 |
+
|
426 |
+
# return url
|
427 |
+
return $public;
|
428 |
+
|
429 |
+
}
|
430 |
}
|
431 |
|
432 |
+
# default
|
433 |
+
return $url;
|
434 |
}
|
435 |
|
436 |
|
437 |
+
|
438 |
+
|
439 |
+
|
440 |
+
|
441 |
+
|
442 |
# check if PHP has some functions disabled
|
443 |
function fvm_function_available($func) {
|
444 |
if (ini_get('safe_mode')) return false;
|
476 |
return sprintf( "%1.{$decimals}f %s", round( $bytes, $decimals ), $units[$i] );
|
477 |
}
|
478 |
|
479 |
+
# purge static cache files directory
|
480 |
+
function fvm_purge_static_files() {
|
481 |
+
|
482 |
+
# globals
|
483 |
+
global $fvm_settings;
|
484 |
+
|
485 |
+
# truncate cache table
|
486 |
+
global $wpdb;
|
487 |
+
if(is_null($wpdb)) { return false; }
|
488 |
+
try {
|
489 |
+
$wpdb->query("TRUNCATE TABLE {$wpdb->prefix}fvm_cache");
|
490 |
+
$wpdb->query("TRUNCATE TABLE {$wpdb->prefix}fvm_logs");
|
491 |
+
} catch (Exception $e) {
|
492 |
+
error_log('Error: '.$e->getMessage(), 0);
|
493 |
+
}
|
494 |
+
|
495 |
+
# increment
|
496 |
+
update_option('fvm_last_cache_update', time());
|
497 |
+
|
498 |
+
# process
|
499 |
+
if( function_exists('wp_upload_dir') ) {
|
500 |
+
|
501 |
+
$upload_dir = wp_upload_dir();
|
502 |
+
if(isset($upload_dir['basedir']) && isset($upload_dir['baseurl']) && !empty($upload_dir['basedir'])) {
|
503 |
+
require_once (ABSPATH . DIRECTORY_SEPARATOR . 'wp-admin'. DIRECTORY_SEPARATOR .'includes'. DIRECTORY_SEPARATOR .'class-wp-filesystem-base.php');
|
504 |
+
require_once (ABSPATH . DIRECTORY_SEPARATOR .'wp-admin'. DIRECTORY_SEPARATOR .'includes'. DIRECTORY_SEPARATOR .'class-wp-filesystem-direct.php');
|
505 |
|
506 |
+
# instant purge
|
507 |
+
global $fvm_settings;
|
508 |
+
if(isset($fvm_settings['cache']['min_instant_purge']) && $fvm_settings['cache']['min_instant_purge'] == true) {
|
509 |
+
$cache_dir = $upload_dir['basedir'] . DIRECTORY_SEPARATOR . 'fvm-cache';
|
510 |
+
$fileSystemDirect = new WP_Filesystem_Direct(false);
|
511 |
+
$fileSystemDirect->rmdir($cache_dir, true);
|
512 |
+
return true;
|
513 |
+
} else {
|
514 |
+
$cache_dir = $upload_dir['basedir'] . DIRECTORY_SEPARATOR . 'fvm-cache'. DIRECTORY_SEPARATOR . 'min';
|
515 |
+
$fileSystemDirect = new WP_Filesystem_Direct(false);
|
516 |
+
|
517 |
+
# older than 3 days
|
518 |
+
$list = $fileSystemDirect->dirlist($cache_dir, false, true);
|
519 |
+
if(is_array($list) && count($list) > 0) {
|
520 |
+
foreach($list as $k=>$arr) {
|
521 |
+
if(isset($arr['lastmodunix']) && $arr['type'] == 'f' && intval($arr['lastmodunix']) <= time()-86400) {
|
522 |
+
$fileSystemDirect->delete($cache_dir . DIRECTORY_SEPARATOR . $arr['name'], false, 'f');
|
523 |
+
}
|
524 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
525 |
}
|
526 |
+
|
527 |
}
|
528 |
+
|
|
|
529 |
}
|
|
|
|
|
|
|
530 |
}
|
|
|
531 |
}
|
532 |
|
533 |
|
618 |
# css
|
619 |
$fvm_settings['css']['enable'] = 1;
|
620 |
$fvm_settings['css']['noprint'] = 1;
|
|
|
|
|
|
|
|
|
621 |
|
622 |
}
|
623 |
|
728 |
|
729 |
}
|
730 |
|
|
|
|
|
|
|
731 |
# mark as done
|
732 |
update_option('fastvelocity_upgraded', true);
|
733 |
|
740 |
}
|
741 |
|
742 |
# save log to database
|
743 |
+
# usage: $arr = array('type'=>'js', 'msg'=>'', 'meta'=>json_encode(array('loc'=>'function')));
|
744 |
function fvm_save_log($arr) {
|
745 |
|
746 |
# must have
|
747 |
+
if(is_null($arr) || !is_array($arr) || !isset($arr['msg'])) { return false; }
|
|
|
748 |
|
749 |
+
# uid, prevent duplicate or unique by date
|
750 |
+
if(!isset($arr['date'])) {
|
751 |
+
$arr['date'] = time();
|
752 |
+
$arr['uid'] = fvm_generate_hash_with_prefix($arr['msg'], 'log');
|
753 |
+
} else {
|
754 |
+
$arr['uid'] = fvm_generate_hash_with_prefix($arr['date'] . ' / ' . $arr['msg'], 'log');
|
755 |
+
}
|
756 |
|
757 |
# initialize arrays (fields, types, values)
|
758 |
$fld = array();
|
759 |
$tpe = array();
|
760 |
$vls = array();
|
761 |
+
|
762 |
+
# define possible fields
|
763 |
+
$all = array('date', 'uid', 'type', 'msg', 'meta');
|
|
|
|
|
764 |
|
765 |
# process only recognized columns
|
766 |
foreach($arr as $k=>$v) {
|
767 |
if(in_array($k, $all)) {
|
768 |
+
$tpe[] = '%s';
|
|
|
|
|
|
|
|
|
|
|
769 |
$fld[] = $k;
|
770 |
$vls[] = $v;
|
771 |
}
|
772 |
}
|
773 |
|
774 |
+
try {
|
775 |
+
|
776 |
+
# connect
|
777 |
+
global $wpdb;
|
778 |
+
if(is_null($wpdb)) { return false; }
|
779 |
+
|
780 |
+
# check if exists before inserting
|
781 |
+
$result = $wpdb->get_row($wpdb->prepare("SELECT id FROM ".$wpdb->prefix."fvm_logs WHERE uid = %s LIMIT 1", $arr['uid']));
|
782 |
+
if(is_null($check) || !isset($result->id)) {
|
783 |
+
|
784 |
+
# prepare and insert to database
|
785 |
+
$wpdb->query($wpdb->prepare("INSERT IGNORE INTO ".$wpdb->prefix."fvm_logs (".implode(', ', $fld).") VALUES (".implode(', ', $tpe).")", $vls));
|
786 |
+
return true;
|
787 |
+
|
788 |
+
}
|
789 |
+
|
790 |
+
} catch (Exception $e) {
|
791 |
+
error_log('Error: '.$e->getMessage(), 0);
|
792 |
}
|
793 |
+
|
794 |
# fallback
|
795 |
return false;
|
796 |
|
797 |
}
|
798 |
|
799 |
|
800 |
+
# generate a 64 char string with prefix
|
801 |
+
function fvm_generate_hash_with_prefix($uid, $prefix) {
|
802 |
+
return substr($prefix .hash('sha256', $uid), 0, 64);
|
803 |
+
}
|
804 |
|
805 |
|
806 |
+
# replace css imports with origin css code
|
807 |
+
function fvm_replace_css_imports($css, $rq=null) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
808 |
|
809 |
+
# globals
|
810 |
+
global $fvm_urls, $fvm_settings;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
811 |
|
812 |
+
# handle import url rules
|
813 |
+
$cssimports = array();
|
814 |
+
preg_match_all ("/@import[ ]*['\"]{0,}(url\()*['\"]*([^\(\{'\"\)]*)['\"\)]*[;]{0,}/ui", $css, $cssimports);
|
815 |
+
if(isset($cssimports[0]) && isset($cssimports[2])) {
|
816 |
+
foreach($cssimports[0] as $k=>$cssimport) {
|
817 |
+
|
818 |
+
# if @import url rule, or guess full url
|
819 |
+
if(stripos($cssimport, 'import url') !== false && isset($cssimports[2][$k])) {
|
820 |
+
$url = trim($cssimports[2][$k]);
|
821 |
+
} else {
|
822 |
+
if(!is_null($rq) && !empty($rq)) {
|
823 |
+
$url = dirname($rq) . '/' . trim($cssimports[2][$k]);
|
824 |
+
}
|
825 |
+
}
|
826 |
+
|
827 |
+
# must have
|
828 |
+
if(!empty($url)) {
|
829 |
+
|
830 |
+
# make sure we have a complete url
|
831 |
+
$href = fvm_normalize_url($url);
|
832 |
+
|
833 |
+
# download, minify, cache (no ver query string)
|
834 |
+
$tkey = fvm_generate_hash_with_prefix($href, 'css');
|
835 |
+
$subcss = fvm_get_transient($tkey);
|
836 |
+
if ($subcss === false) {
|
837 |
+
|
838 |
+
# get minification settings for files
|
839 |
+
if(isset($fvm_settings['css']['css_enable_min_files'])) {
|
840 |
+
$enable_css_minification = $fvm_settings['css']['css_enable_min_files'];
|
841 |
+
}
|
842 |
+
|
843 |
+
# force minification on google fonts
|
844 |
+
if(stripos($href, 'fonts.googleapis.com') !== false) {
|
845 |
+
$enable_css_minification = true;
|
846 |
+
}
|
847 |
+
|
848 |
+
# download file, get contents, merge
|
849 |
+
$ddl = array();
|
850 |
+
$ddl = fvm_maybe_download($href);
|
851 |
+
|
852 |
+
# if success
|
853 |
+
if(isset($ddl['content'])) {
|
854 |
+
|
855 |
+
# contents
|
856 |
+
$subcss = $ddl['content'];
|
857 |
+
|
858 |
+
# minify
|
859 |
+
$subcss = fvm_maybe_minify_css_file($subcss, $href, $enable_css_minification);
|
860 |
+
|
861 |
+
# trim code
|
862 |
+
$subcss = trim($subcss);
|
863 |
+
|
864 |
+
# save
|
865 |
+
fvm_set_transient(array('uid'=>$tkey, 'date'=>$tvers, 'type'=>'css', 'content'=>$subcss));
|
866 |
+
}
|
867 |
+
}
|
868 |
+
|
869 |
+
# replace import rule with inline code
|
870 |
+
if ($subcss !== false && !empty($subcss)) {
|
871 |
+
$css = str_replace($cssimport, $subcss, $css);
|
872 |
+
}
|
873 |
+
|
874 |
+
}
|
875 |
+
}
|
876 |
+
}
|
877 |
|
878 |
+
# return
|
879 |
+
return trim($css);
|
880 |
+
|
881 |
+
}
|
882 |
+
|
883 |
|
884 |
+
# remove fonts and icons from final css
|
885 |
+
function fvm_extract_fonts($css_code) {
|
886 |
+
|
887 |
+
global $fvm_settings, $fvm_urls;
|
888 |
+
$critical_fonts = array();
|
889 |
+
$mff = array();
|
890 |
+
$css_preload = array();
|
891 |
+
$css_code_ff = '';
|
892 |
+
|
893 |
+
# get list of fonts that are on the critical path and are to be left alone
|
894 |
+
if( isset($fvm_settings['css']['css_optimize_critical_fonts']) &&
|
895 |
+
!empty($fvm_settings['css']['css_optimize_critical_fonts'])) {
|
896 |
+
$critical_fonts = fvm_string_toarray($fvm_settings['css']['css_optimize_critical_fonts']);
|
897 |
}
|
898 |
|
899 |
+
# extract font faces
|
900 |
+
preg_match_all('/\@\s*font-face\s*\{([^}]+)\}/iUu', $css_code, $mff);
|
901 |
+
if(isset($mff[0]) && is_array($mff[0])) {
|
902 |
+
foreach($mff[0] as $ff) {
|
903 |
+
|
904 |
+
# strip and collect
|
905 |
+
$css_code = str_replace($ff, '', $css_code);
|
906 |
+
$css_code_ff.= $ff . PHP_EOL;
|
907 |
|
908 |
+
}
|
909 |
+
}
|
910 |
+
|
911 |
+
# relative paths
|
912 |
+
$css_code_ff = str_replace('https://'.$fvm_urls['wp_domain'], '', $css_code_ff);
|
913 |
+
$css_code_ff = str_replace('http://'.$fvm_urls['wp_domain'], '', $css_code_ff);
|
914 |
+
$css_code_ff = str_replace('//'.$fvm_urls['wp_domain'], '', $css_code_ff);
|
915 |
|
916 |
+
# return
|
917 |
+
$result = array('code'=>$css_code, 'fonts'=>$css_code_ff);
|
918 |
+
return $result;
|
919 |
+
}
|
920 |
+
|
921 |
+
|
922 |
+
# rewrite assets to cdn
|
923 |
+
function fvm_process_cdn($html) {
|
924 |
+
|
925 |
+
# settings
|
926 |
+
global $fvm_settings, $fvm_urls;
|
927 |
+
|
928 |
+
# html must be an object
|
929 |
+
if (!is_object($html)) {
|
930 |
+
$nobj = 1;
|
931 |
+
$html = str_get_html($html, true, true, 'UTF-8', false, PHP_EOL, ' ');
|
932 |
+
}
|
933 |
+
|
934 |
+
# default integration
|
935 |
+
$integration_defaults = array('a[data-interchange*=/wp-content/], div[data-background-image], section[data-background-image], form[data-product_variations], image[height], img[src*=/wp-content/], img[data-src*=/wp-content/], img[data-srcset*=/wp-content/], link[rel=icon], link[rel=apple-touch-icon], meta[name=msapplication-TileImage], picture source[srcset*=/wp-content/], rs-slide[data-thumb], video source[type*=video]');
|
936 |
+
|
937 |
+
# html integration
|
938 |
+
if(isset($fvm_urls['wp_domain']) && isset($fvm_settings['cdn']['domain']) && isset($fvm_settings['cdn']['integration'])) {
|
939 |
+
if(!empty($fvm_settings['cdn']['domain']) && !empty($fvm_urls['wp_domain'])) {
|
940 |
+
$arr = fvm_string_toarray($fvm_settings['cdn']['integration']);
|
941 |
+
$arr = array_unique(array_merge($arr, $integration_defaults)); # add defaults
|
942 |
+
if(is_array($arr) && count($arr) > 0) {
|
943 |
+
foreach($html->find(implode(', ', $arr) ) as $elem) {
|
944 |
+
|
945 |
+
# preserve some attributes but replace others
|
946 |
+
if (is_object($elem) && isset($elem->attr)) {
|
947 |
+
|
948 |
+
# get all attributes
|
949 |
+
foreach ($elem->attr as $key=>$val) {
|
950 |
+
|
951 |
+
# skip href attribute for links
|
952 |
+
if($key == 'href' && stripos($elem->outertext, '<a ') !== false) { continue; }
|
953 |
+
|
954 |
+
# skip certain attributes
|
955 |
+
if(in_array($key, array('id', 'class', 'action'))) { continue; }
|
956 |
+
|
957 |
+
# scheme + site url
|
958 |
+
$fcdn = str_replace($fvm_urls['wp_domain'], $fvm_settings['cdn']['domain'], $fvm_urls['wp_site_url']);
|
959 |
+
|
960 |
+
# known replacements
|
961 |
+
$elem->{$key} = str_ireplace('url(/wp-content/', 'url('.$fcdn.'/wp-content/', $elem->{$key});
|
962 |
+
$elem->{$key} = str_ireplace('url("/wp-content/', 'url("'.$fcdn.'/wp-content/', $elem->{$key});
|
963 |
+
$elem->{$key} = str_ireplace('url(\'/wp-content/', 'url(\''.$fcdn.'/wp-content/', $elem->{$key});
|
964 |
+
|
965 |
+
# normalize certain field
|
966 |
+
if(in_array($key, array('src', 'data-bg', 'data-lazy-src', 'audio', 'poster'))) {
|
967 |
+
$elem->{$key} = fvm_normalize_url($elem->{$key});
|
968 |
+
}
|
969 |
+
|
970 |
+
# replace other attributes
|
971 |
+
$elem->{$key} = str_replace('//'.$fvm_urls['wp_domain'], '//'.$fvm_settings['cdn']['domain'], $elem->{$key});
|
972 |
+
$elem->{$key} = str_replace('\/\/'.$fvm_urls['wp_domain'], '\/\/'.$fvm_settings['cdn']['domain'], $elem->{$key});
|
973 |
+
|
974 |
+
}
|
975 |
+
|
976 |
+
}
|
977 |
+
|
978 |
+
}
|
979 |
+
}
|
980 |
}
|
981 |
}
|
982 |
|
983 |
+
|
984 |
+
# add CDN support to Styles, CSS and JS files
|
985 |
+
|
986 |
+
# css
|
987 |
+
if(isset($fvm_settings['cdn']['cssok']) && $fvm_settings['cdn']['cssok'] == true) {
|
988 |
+
|
989 |
+
# scheme + site url
|
990 |
+
$fcdn = str_replace($fvm_urls['wp_domain'], $fvm_settings['cdn']['domain'], $fvm_urls['wp_site_url']);
|
991 |
+
|
992 |
+
# replace inside styles
|
993 |
+
foreach($html->find('style') as $elem) {
|
994 |
+
|
995 |
+
# fetch
|
996 |
+
$css = $elem->outertext;
|
997 |
+
|
998 |
+
# known replacements
|
999 |
+
$css = str_ireplace('url(/wp-content/', 'url('.$fcdn.'/wp-content/', $css);
|
1000 |
+
$css = str_ireplace('url("/wp-content/', 'url("'.$fcdn.'/wp-content/', $css);
|
1001 |
+
$css = str_ireplace('url(\'/wp-content/', 'url(\''.$fcdn.'/wp-content/', $css);
|
1002 |
+
$css = str_replace('//'.$fvm_urls['wp_domain'], '//'.$fvm_settings['cdn']['domain'], $css);
|
1003 |
+
|
1004 |
+
# save
|
1005 |
+
$elem->outertext = $css;
|
1006 |
+
|
1007 |
+
}
|
1008 |
+
|
1009 |
+
# replace link stylesheets
|
1010 |
+
if(isset($fvm_settings['cdn']['enable_css']) && $fvm_settings['cdn']['enable_css'] == true) {
|
1011 |
+
foreach($html->find('link[rel=stylesheet], link[rel=preload]') as $elem) {
|
1012 |
+
if(isset($elem->href)) {
|
1013 |
+
$elem->href = str_replace($fvm_urls['wp_site_url'], $fcdn, $elem->href);
|
1014 |
+
}
|
1015 |
+
}
|
1016 |
+
}
|
1017 |
+
}
|
1018 |
+
|
1019 |
+
# js
|
1020 |
+
if(isset($fvm_settings['cdn']['jsok']) && $fvm_settings['cdn']['jsok'] == true) {
|
1021 |
+
|
1022 |
+
# replace script files
|
1023 |
+
foreach($html->find('script') as $elem) {
|
1024 |
+
|
1025 |
+
# js files
|
1026 |
+
if(isset($fvm_settings['cdn']['enable_js']) && $fvm_settings['cdn']['enable_js'] == true) {
|
1027 |
+
if(isset($elem->src) && stripos($elem->src, $fvm_urls['wp_domain']) !== false) {
|
1028 |
+
$elem->src = str_replace('//'.$fvm_urls['wp_domain'], '//'.$fvm_settings['cdn']['domain'], $elem->src);
|
1029 |
+
}
|
1030 |
+
}
|
1031 |
+
}
|
1032 |
+
|
1033 |
+
}
|
1034 |
+
|
1035 |
+
# convert html object to string, only when needed
|
1036 |
+
if(isset($nobj) && $nobj == 1) {
|
1037 |
+
$html = trim($html->save());
|
1038 |
+
}
|
1039 |
+
|
1040 |
+
# return
|
1041 |
+
return $html;
|
1042 |
}
|
1043 |
|
1044 |
|
1045 |
+
# rewrite url with cdn
|
1046 |
+
function fvm_rewrite_cdn_url($url) {
|
1047 |
+
global $fvm_settings, $fvm_urls;
|
1048 |
+
if(isset($fvm_settings['cdn']['enable']) && $fvm_settings['cdn']['enable'] == true && isset($fvm_settings['cdn']['domain']) && !empty($fvm_settings['cdn']['domain'])) {
|
1049 |
+
$url = str_replace('//'.$fvm_urls['wp_domain'], '//'.$fvm_settings['cdn']['domain'], $url);
|
1050 |
+
}
|
1051 |
+
return $url;
|
1052 |
+
}
|
1053 |
+
|
1054 |
+
# get css font-face rules, original + simplified
|
1055 |
+
function fvm_simplify_fontface($css_code) {
|
1056 |
+
|
1057 |
+
$mff = array();
|
1058 |
+
$before = array();
|
1059 |
+
$after = array();
|
1060 |
+
|
1061 |
+
# extract font faces
|
1062 |
+
preg_match_all('/\@\s*font-face\s*\{([^}]+)\}/iUu', $css_code, $mff);
|
1063 |
+
if(isset($mff[0]) && isset($mff[1]) && is_array($mff[1])) {
|
1064 |
+
foreach($mff[1] as $kf=>$ff) {
|
1065 |
|
1066 |
+
# simplify font urls
|
1067 |
+
$cssrules = preg_split("/;(?![^(]*\))/iu", $ff);
|
1068 |
+
foreach ($cssrules as $k=>$csr) {
|
1069 |
+
if(preg_match('/src\s*\:\s*url/Uui', $csr)) {
|
1070 |
+
|
1071 |
+
# woff
|
1072 |
+
$fonts = array();
|
1073 |
+
preg_match('/url\s*\(\s*[\'\"]*([^,\'\"]*)[\'\"]*\)\s*format\s*\([\'\"]*woff[\'\"]*\s*\)/Uui', $csr, $fonts);
|
1074 |
+
if(isset($fonts[0])) { $cssrules[$k] = 'src:'.$fonts[0]; break; }
|
1075 |
|
1076 |
+
# woff2
|
1077 |
+
$fonts = array();
|
1078 |
+
preg_match('/url\s*\(\s*[\'\"]*([^,\'\"]*)[\'\"]*\)\s*format\s*\([\'\"]*woff2[\'\"]*\s*\)/Uui', $csr, $fonts);
|
1079 |
+
if(isset($fonts[0])) { $cssrules[$k] = 'src:'.$fonts[0]; break; }
|
1080 |
+
|
1081 |
+
# svg
|
1082 |
+
$fonts = array();
|
1083 |
+
preg_match('/url\s*\(\s*[\'\"]*([^,\'\"]*)[\'\"]*\)\s*format\s*\([\'\"]*svg[\'\"]*\s*\)/Uui', $csr, $fonts);
|
1084 |
+
if(isset($fonts[0])) { $cssrules[$k] = 'src:'.$fonts[0]; break; }
|
1085 |
+
|
1086 |
+
# truetype
|
1087 |
+
$fonts = array();
|
1088 |
+
preg_match('/url\s*\(\s*[\'\"]*([^,\'\"]*)[\'\"]*\)\s*format\s*\([\'\"]*truetype[\'\"]*\s*\)/Uui', $csr, $fonts);
|
1089 |
+
if(isset($fonts[0])) { $cssrules[$k] = 'src:'.$fonts[0]; break; }
|
1090 |
+
|
1091 |
+
# delete other src:url rules
|
1092 |
+
if(stripos($csr, 'format') === false) {
|
1093 |
+
unset($cssrules[$k]);
|
1094 |
+
}
|
1095 |
+
|
1096 |
+
}
|
1097 |
+
}
|
1098 |
+
|
1099 |
+
# merge and create font face rule
|
1100 |
+
$after[] = '@font-face{'.implode(';', $cssrules).'}';
|
1101 |
|
1102 |
+
# strip and collect
|
1103 |
+
$before[] = $mff[0][$kf];
|
1104 |
|
1105 |
+
}
|
1106 |
+
}
|
|
|
|
|
1107 |
|
1108 |
+
# return
|
1109 |
+
if(count($before) > 0) {
|
1110 |
+
return array('before'=>$before, 'after'=>$after);
|
1111 |
+
} else {
|
1112 |
+
return false;
|
1113 |
+
}
|
1114 |
}
|
1115 |
|
1116 |
|
1117 |
+
|
1118 |
+
# get css code from css file
|
1119 |
+
function fvm_get_css_from_file($tag) {
|
1120 |
|
1121 |
+
# globals
|
1122 |
+
global $fvm_urls, $fvm_settings;
|
|
|
1123 |
|
1124 |
+
# variables
|
1125 |
+
$tvers = get_option('fvm_last_cache_update', '0');
|
1126 |
+
|
1127 |
+
# make sure we have a complete url
|
1128 |
+
$href = fvm_normalize_url($tag->href);
|
1129 |
+
|
1130 |
+
# download, minify, cache (no ver query string)
|
1131 |
+
$tkey = fvm_generate_hash_with_prefix($href, 'css');
|
1132 |
+
$css = fvm_get_transient($tkey);
|
1133 |
+
|
1134 |
+
# download
|
1135 |
+
if ($css === false) {
|
1136 |
+
|
1137 |
+
$ddl = array();
|
1138 |
+
$ddl = fvm_maybe_download($href);
|
1139 |
+
|
1140 |
+
# success
|
1141 |
+
if(isset($ddl['content'])) {
|
1142 |
+
|
1143 |
+
# minify flag
|
1144 |
+
$min = false;
|
1145 |
+
if(isset($fvm_settings['css']['css_enable_min_files']) && $fvm_settings['css']['css_enable_min_files'] == true) {
|
1146 |
+
$min = true;
|
1147 |
+
}
|
1148 |
+
|
1149 |
+
# minify
|
1150 |
+
$css = fvm_maybe_minify_css_file($ddl['content'], $href, $min);
|
1151 |
+
|
1152 |
+
# quick integrity check
|
1153 |
+
if($css !== false) {
|
1154 |
+
|
1155 |
+
# handle import rules
|
1156 |
+
$css = fvm_replace_css_imports($css, $href);
|
1157 |
+
$meta = json_encode(array('href'=>$href));
|
1158 |
+
|
1159 |
+
# save transient
|
1160 |
+
$verify = fvm_set_transient(array('uid'=>$tkey, 'date'=>$tvers, 'type'=>'css', 'content'=>$css, 'meta'=>$meta));
|
1161 |
+
|
1162 |
+
# success, from download
|
1163 |
+
return array('code'=>$css, 'tkey'=>$tkey, 'url'=> $href);
|
1164 |
+
}
|
1165 |
+
}
|
1166 |
|
|
|
|
|
|
|
1167 |
} else {
|
1168 |
+
# success, from transient
|
1169 |
+
return array('code'=>$css, 'tkey'=>$tkey, 'url'=> $href);
|
1170 |
}
|
1171 |
+
|
1172 |
+
# fallback
|
1173 |
+
return false;
|
1174 |
+
|
1175 |
+
}
|
1176 |
|
1177 |
+
|
1178 |
+
# get js code from css file
|
1179 |
+
function fvm_get_js_from_file($tag) {
|
1180 |
|
1181 |
+
# globals
|
1182 |
+
global $fvm_urls, $fvm_settings;
|
1183 |
+
|
1184 |
+
# variables
|
1185 |
+
$tvers = get_option('fvm_last_cache_update', '0');
|
1186 |
+
|
1187 |
+
# make sure we have a complete url
|
1188 |
+
$href = fvm_normalize_url($tag->src);
|
1189 |
+
|
1190 |
+
# download, minify, cache (no ver query string)
|
1191 |
+
$tkey = fvm_generate_hash_with_prefix($href, 'js');
|
1192 |
+
$js = fvm_get_transient($tkey);
|
1193 |
+
|
1194 |
+
# download
|
1195 |
+
if ($js === false) {
|
1196 |
+
|
1197 |
+
$ddl = array();
|
1198 |
+
$ddl = fvm_maybe_download($href);
|
1199 |
+
|
1200 |
+
# success
|
1201 |
+
if(isset($ddl['content'])) {
|
1202 |
+
|
1203 |
+
# minify?
|
1204 |
+
if(!isset($fvm_settings['js']['min_disable_inline']) || (isset($fvm_settings['js']['min_disable_inline'])&& $fvm_settings['js']['min_disable_inline'] != true)) {
|
1205 |
+
$js = fvm_maybe_minify_js($ddl['content'], $href, true);
|
1206 |
+
}
|
1207 |
+
|
1208 |
+
# wrap with try catch
|
1209 |
+
$js = fvm_try_catch_wrap($js, $href);
|
1210 |
+
|
1211 |
+
# quick integrity check
|
1212 |
+
if($js !== false) {
|
1213 |
+
|
1214 |
+
# meta
|
1215 |
+
$meta = json_encode(array('href'=>$href));
|
1216 |
+
|
1217 |
+
# save transient
|
1218 |
+
$verify = fvm_set_transient(array('uid'=>$tkey, 'date'=>$tvers, 'type'=>'js', 'content'=>$js, 'meta'=>$meta));
|
1219 |
+
|
1220 |
+
# success, from download
|
1221 |
+
return array('code'=>$js, 'tkey'=>$tkey, 'url'=> $href);
|
1222 |
+
}
|
1223 |
+
}
|
1224 |
+
|
1225 |
+
} else {
|
1226 |
+
# success, from transient
|
1227 |
+
return array('code'=>$js, 'tkey'=>$tkey, 'url'=> $href);
|
1228 |
}
|
1229 |
|
1230 |
+
# fallback
|
1231 |
+
return false;
|
1232 |
+
|
1233 |
+
}
|
1234 |
+
|
1235 |
+
|
1236 |
+
|
1237 |
+
|
1238 |
+
# get transients
|
1239 |
+
function fvm_get_transient($key, $check=null, $with_meta=null) {
|
1240 |
+
|
1241 |
+
# must have
|
1242 |
+
global $wpdb;
|
1243 |
+
if(is_null($wpdb)) { return false; }
|
1244 |
+
$db_prefix = $wpdb->prefix;
|
1245 |
+
|
1246 |
+
try {
|
1247 |
+
|
1248 |
+
# check or fetch
|
1249 |
+
if(!is_null($check)) {
|
1250 |
+
$sql = $wpdb->prepare("SELECT id FROM {$db_prefix}fvm_cache WHERE uid = %s LIMIT 1", $key);
|
1251 |
+
} else if (!is_null($with_meta)) {
|
1252 |
+
$sql = $wpdb->prepare("SELECT date, content, meta FROM {$db_prefix}fvm_cache WHERE uid = %s LIMIT 1", $key);
|
1253 |
+
} else {
|
1254 |
+
$sql = $wpdb->prepare("SELECT content FROM {$db_prefix}fvm_cache WHERE uid = %s LIMIT 1", $key);
|
1255 |
+
}
|
1256 |
+
|
1257 |
+
# get result from database
|
1258 |
+
$result = $wpdb->get_row($sql);
|
1259 |
+
|
1260 |
+
# return true if just checking
|
1261 |
+
if(!is_null($check) && isset($result->id)) {
|
1262 |
+
return true;
|
1263 |
+
}
|
1264 |
+
|
1265 |
+
# return content only
|
1266 |
+
if(is_null($check) && is_null($with_meta) && isset($result->content)) {
|
1267 |
+
return $result->content;
|
1268 |
+
}
|
1269 |
+
|
1270 |
+
# return content and meta
|
1271 |
+
if(is_null($check) && !is_null($with_meta) && isset($result->date) && isset($result->content) && isset($result->meta)) {
|
1272 |
+
return array('date'=>$result->date, 'content'=>$result->content, 'meta'=>json_decode($result->meta, true), 'cache-method'=>$cache_method);
|
1273 |
+
}
|
1274 |
+
|
1275 |
+
} catch (Exception $e) {
|
1276 |
+
error_log('Error: '.$e->getMessage(), 0);
|
1277 |
+
return false;
|
1278 |
}
|
1279 |
|
1280 |
# fallback
|
1286 |
|
1287 |
# must have
|
1288 |
if(!is_array($arr) || (is_array($arr) && (count($arr) == 0 || empty($arr)))) { return false; }
|
1289 |
+
if(!isset($arr['uid']) || !isset($arr['date']) || !isset($arr['type']) || !isset($arr['content'])) { return false; }
|
1290 |
|
1291 |
# normalize unknown keys
|
1292 |
+
if(strlen($arr['uid']) != 64) { $arr['uid'] = fvm_generate_hash_with_prefix($arr['uid'], $arr['type']); }
|
1293 |
|
1294 |
+
# check if it already exists, return early if it does
|
1295 |
$status = fvm_get_transient($arr['uid'], true);
|
1296 |
+
if($status) { return $arr['uid']; }
|
1297 |
+
|
1298 |
+
# must have
|
1299 |
global $wpdb;
|
1300 |
+
if(is_null($wpdb)) { return false; }
|
1301 |
+
$db_prefix = $wpdb->prefix;
|
1302 |
|
1303 |
# initialize arrays (fields, types, values)
|
1304 |
$fld = array();
|
1314 |
foreach($arr as $k=>$v) {
|
1315 |
if(in_array($k, $all)) {
|
1316 |
if(in_array($k, $str)) { $tpe[] = '%s'; } else { $tpe[] = '%d'; }
|
|
|
1317 |
$fld[] = $k;
|
1318 |
$vls[] = $v;
|
1319 |
}
|
1320 |
}
|
|
|
|
|
|
|
|
|
|
|
1321 |
|
1322 |
+
try {
|
1323 |
+
# prepare and insert to database
|
1324 |
+
$result = $wpdb->query($wpdb->prepare("INSERT IGNORE INTO {$db_prefix}fvm_cache (".implode(', ', $fld).") VALUES (".implode(', ', $tpe).")", $vls));
|
1325 |
+
|
1326 |
+
# success
|
1327 |
+
if($result) {
|
1328 |
+
return $arr['uid'];
|
1329 |
+
}
|
1330 |
+
} catch (Exception $e) {
|
1331 |
+
error_log('Error: '.$e->getMessage(), 0);
|
1332 |
}
|
1333 |
+
|
1334 |
# fallback
|
1335 |
return false;
|
1336 |
|
1339 |
# delete transient
|
1340 |
function fvm_del_transient($key) {
|
1341 |
|
|
|
|
|
1342 |
# normalize unknown keys
|
1343 |
+
if(strlen($key) != 64) { $key = fvm_generate_hash_with_prefix($key, ''); }
|
1344 |
|
1345 |
+
# must have
|
1346 |
+
global $wpdb;
|
1347 |
+
if(is_null($wpdb)) { return false; }
|
1348 |
+
$db_prefix = $wpdb->prefix;
|
1349 |
+
|
1350 |
+
try {
|
1351 |
+
# delete
|
1352 |
+
$wpdb->query($wpdb->prepare("DELETE FROM {$db_prefix}fvm_cache WHERE uid = %s", $key));
|
1353 |
+
return true;
|
1354 |
+
} catch (Exception $e) {
|
1355 |
+
error_log('Error: '.$e->getMessage(), 0);
|
1356 |
+
}
|
1357 |
+
|
1358 |
+
# fallback
|
1359 |
+
return false;
|
1360 |
}
|
1361 |
|
1362 |
|
1363 |
# functions, get full url
|
1364 |
+
function fvm_normalize_url($href, $purl=null) {
|
1365 |
|
1366 |
# preserve empty source handles
|
1367 |
+
$href = trim($href);
|
1368 |
+
if(empty($href)) { return false; }
|
1369 |
|
1370 |
# some fixes
|
1371 |
+
$href = str_replace(array('&', '&'), '&', $href);
|
|
|
|
|
|
|
1372 |
|
1373 |
+
# external url
|
1374 |
+
if(!is_null($purl) && !empty($purl)) {
|
1375 |
+
$parse = parse_url($purl);
|
1376 |
+
} else {
|
1377 |
+
# local url
|
1378 |
+
global $fvm_urls;
|
1379 |
+
$parse = parse_url($fvm_urls['wp_site_url']);
|
1380 |
+
}
|
1381 |
+
|
1382 |
+
# domain info
|
1383 |
+
$scheme = $parse['scheme'];
|
1384 |
+
$host = $parse['host'];
|
1385 |
+
$path = $parse['path'];
|
1386 |
+
|
1387 |
+
# relative to full urls
|
1388 |
+
if (substr($href, 0, 2) === "//") {
|
1389 |
+
$href = $scheme.':'.$href; # scheme missing
|
1390 |
+
} else if (substr($href, 0, 1) === "/") {
|
1391 |
+
$href = $scheme.'://'.$host . $href; # scheme and domain missing
|
1392 |
+
} else if (substr($href, 0, 3) === '../' && !is_null($purl) && !empty($purl)) {
|
1393 |
+
$href = $scheme.':'.$host . dirname($path) . '/' . $href;
|
1394 |
+
} else if ($scheme == 'https' && substr($href, 0, 4) == 'http' && substr($href, 0, 5) !== $scheme) {
|
1395 |
+
$href = str_replace('http://', 'https://', $href); # force https
|
1396 |
+
} else {
|
1397 |
+
# url should be fine
|
1398 |
}
|
1399 |
|
1400 |
+
# prevent double forward slashes in the middle
|
1401 |
+
$href = str_replace('###', '://', str_replace('//', '/', str_replace('://', '###', $href)));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1402 |
|
1403 |
+
return $href;
|
1404 |
}
|
1405 |
|
1406 |
|
1407 |
# minify ld+json scripts
|
1408 |
function fvm_minify_microdata($data) {
|
|
|
1409 |
$data = trim(preg_replace('/(\v)+(\h)+[\/]{2}(.*)+(\v)+/u', '', $data));
|
|
|
|
|
1410 |
$data = trim(preg_replace('/\s+/u', ' ', $data));
|
1411 |
$data = str_replace(array('" ', ' "'), '"', $data);
|
1412 |
$data = str_replace(array('[ ', ' ['), '[', $data);
|
1437 |
|
1438 |
# find if a string looks like HTML content
|
1439 |
function fvm_is_html($html) {
|
1440 |
+
|
1441 |
# return early if it's html
|
1442 |
$html = trim($html);
|
1443 |
$a = '<!doctype';
|
1481 |
|
1482 |
}
|
1483 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1484 |
# ensure that string is utf8
|
1485 |
function fvm_ensure_utf8($str) {
|
1486 |
$enc = mb_detect_encoding($str, mb_list_encodings(), true);
|
1497 |
}
|
1498 |
|
1499 |
|
1500 |
+
# check if we can process the page, minimum filters
|
1501 |
+
function fvm_can_process_common() {
|
1502 |
+
global $fvm_settings, $fvm_urls;
|
1503 |
|
1504 |
+
# only GET requests allowed
|
1505 |
+
if ($_SERVER['REQUEST_METHOD'] !== 'GET') {
|
1506 |
+
return false;
|
1507 |
+
}
|
1508 |
|
1509 |
+
# always skip on these tasks
|
1510 |
+
if( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ){ return false; }
|
1511 |
+
if( defined('WP_INSTALLING') && WP_INSTALLING ){ return false; }
|
1512 |
+
if( defined('WP_REPAIRING') && WP_REPAIRING ){ return false; }
|
1513 |
+
if( defined('WP_IMPORTING') && WP_IMPORTING ){ return false; }
|
1514 |
+
if( defined('DOING_AJAX') && DOING_AJAX ){ return false; }
|
1515 |
+
if( defined('WP_CLI') && WP_CLI ){ return false; }
|
1516 |
+
if( defined('XMLRPC_REQUEST') && XMLRPC_REQUEST ){ return false; }
|
1517 |
+
if( defined('WP_ADMIN') && WP_ADMIN ){ return false; }
|
1518 |
+
if( defined('SHORTINIT') && SHORTINIT ){ return false; }
|
1519 |
+
if( defined('IFRAME_REQUEST') && IFRAME_REQUEST ){ return false; }
|
1520 |
|
1521 |
+
# detect api requests (only defined after parse_request hook)
|
1522 |
+
if( defined('REST_REQUEST') && REST_REQUEST ){ return false; }
|
1523 |
+
|
1524 |
+
# don't minify specific WordPress areas
|
1525 |
+
if(function_exists('is_404') && is_404()){ return false; }
|
1526 |
+
if(function_exists('is_feed') && is_feed()){ return false; }
|
1527 |
+
if(function_exists('is_comment_feed') && is_comment_feed()){ return false; }
|
1528 |
+
if(function_exists('is_attachment') && is_attachment()){ return false; }
|
1529 |
+
if(function_exists('is_trackback') && is_trackback()){ return false; }
|
1530 |
+
if(function_exists('is_robots') && is_robots()){ return false; }
|
1531 |
+
if(function_exists('is_preview') && is_preview()){ return false; }
|
1532 |
+
if(function_exists('is_customize_preview') && is_customize_preview()){ return false; }
|
1533 |
+
if(function_exists('is_embed') && is_embed()){ return false; }
|
1534 |
+
if(function_exists('is_admin') && is_admin()){ return false; }
|
1535 |
+
if(function_exists('is_blog_admin') && is_blog_admin()){ return false; }
|
1536 |
+
if(function_exists('is_network_admin') && is_network_admin()){ return false; }
|
1537 |
+
|
1538 |
+
# don't minify specific WooCommerce areas
|
1539 |
+
if(function_exists('is_checkout') && is_checkout()){ return false; }
|
1540 |
+
if(function_exists('is_account_page') && is_account_page()){ return false; }
|
1541 |
+
if(function_exists('is_ajax') && is_ajax()){ return false; }
|
1542 |
+
if(function_exists('is_wc_endpoint_url') && is_wc_endpoint_url()){ return false; }
|
1543 |
+
|
1544 |
+
# get requested hostname
|
1545 |
+
$host = fvm_get_domain();
|
1546 |
+
|
1547 |
+
# only for hosts matching the site_url
|
1548 |
+
if(isset($fvm_urls['wp_domain']) && !empty($fvm_urls['wp_domain'])) {
|
1549 |
+
if($host != $fvm_urls['wp_domain']) {
|
1550 |
+
return false;
|
1551 |
+
}
|
1552 |
+
}
|
1553 |
+
|
1554 |
+
# if there is an url, skip common static files
|
1555 |
+
if(isset($_SERVER['REQUEST_URI']) && !empty($_SERVER['REQUEST_URI'])) {
|
1556 |
+
|
1557 |
+
# parse url (path, query)
|
1558 |
+
$ruri = fvm_get_uripath();
|
1559 |
+
|
1560 |
+
# no cache by extension as well, such as robots.txt and other situations
|
1561 |
+
$noext = array('.txt', '.xml', '.xsl', '.map', '.css', '.js', '.png', '.jpeg', '.jpg', '.gif', '.webp', '.ico', '.php', '.htaccess', '.json', '.pdf', '.mp4', '.webm');
|
1562 |
+
foreach ($noext as $ext) {
|
1563 |
+
if(substr($ruri, -strlen($ext)) == $ext) {
|
1564 |
+
return false;
|
1565 |
+
}
|
1566 |
+
}
|
1567 |
+
|
1568 |
+
}
|
1569 |
+
|
1570 |
+
# default
|
1571 |
+
return true;
|
1572 |
+
}
|
1573 |
+
|
1574 |
+
# check if the user is logged in, and if the user role allows optimization
|
1575 |
+
function fvm_user_role_processing_allowed($group) {
|
1576 |
+
if(function_exists('is_user_logged_in') && function_exists('wp_get_current_user')) {
|
1577 |
+
if(is_user_logged_in()) {
|
1578 |
+
|
1579 |
+
# get user roles
|
1580 |
+
global $fvm_settings;
|
1581 |
+
$user = wp_get_current_user();
|
1582 |
+
$roles = (array) $user->roles;
|
1583 |
+
foreach($roles as $role) {
|
1584 |
+
if(isset($fvm_settings['minify'][$role]) && $fvm_settings['minify'][$role] == true) {
|
1585 |
+
return true;
|
1586 |
+
}
|
1587 |
+
}
|
1588 |
+
|
1589 |
+
# disable for other logged in users by default
|
1590 |
+
return false;
|
1591 |
+
}
|
1592 |
+
}
|
1593 |
+
|
1594 |
+
# allow by default
|
1595 |
+
return true;
|
1596 |
+
}
|
1597 |
+
|
1598 |
+
# check if we can process the page, minimum filters
|
1599 |
+
function fvm_can_process_query_string($loc) {
|
1600 |
+
|
1601 |
+
# host and uri path
|
1602 |
+
$host = fvm_get_domain();
|
1603 |
+
$request_uri = fvm_get_uripath(true);
|
1604 |
+
$scheme = fvm_get_scheme();
|
1605 |
+
$url = $scheme.'://'.$host.$request_uri;
|
1606 |
+
$parse = parse_url($url);
|
1607 |
+
|
1608 |
+
# parse query string to array, check if should be ignored
|
1609 |
+
if(isset($parse["query"]) && !empty($parse["query"])) {
|
1610 |
+
|
1611 |
+
# check
|
1612 |
+
$qsarr = array(); parse_str($parse["query"], $qsarr);
|
1613 |
+
|
1614 |
+
# allowed queries by default
|
1615 |
+
if(isset($qsarr['s'])) { unset($qsarr['s']); } # search
|
1616 |
+
if(isset($qsarr['lang'])) { unset($qsarr['lang']); } # wpml
|
1617 |
+
|
1618 |
+
# if there are other queries left, bypass cache
|
1619 |
+
if(count($qsarr) > 0) {
|
1620 |
+
return false;
|
1621 |
+
}
|
1622 |
+
}
|
1623 |
+
|
1624 |
+
# allow by default
|
1625 |
+
return true;
|
1626 |
+
}
|
1627 |
+
|
1628 |
+
|
1629 |
+
|
1630 |
+
# check if page is amp
|
1631 |
+
function fvm_is_amp_page() {
|
1632 |
+
|
1633 |
+
# don't minify amp pages by the amp plugin
|
1634 |
+
if(function_exists('is_amp_endpoint') && is_amp_endpoint()){ return true; }
|
1635 |
+
if(function_exists('ampforwp_is_amp_endpoint') && ampforwp_is_amp_endpoint()){ return true; }
|
1636 |
+
|
1637 |
+
# query string or /amp/
|
1638 |
+
if(isset($_GET['amp'])) { return true; }
|
1639 |
+
if(substr(fvm_get_uripath(), -5) == '/amp/') { return true; }
|
1640 |
+
|
1641 |
+
# not amp
|
1642 |
+
return false;
|
1643 |
+
}
|
1644 |
+
|
1645 |
+
|
1646 |
+
# validate and minify css
|
1647 |
+
function fvm_maybe_minify_css_file($css, $url, $min) {
|
1648 |
+
|
1649 |
# process css only if it's not php or html
|
1650 |
if(fvm_not_php_html($css)) {
|
1651 |
+
|
1652 |
+
global $fvm_settings, $fvm_urls;
|
1653 |
+
|
1654 |
+
# do not minify files in the ignore list
|
1655 |
+
if(isset($fvm_settings['css']['css_ignore_min']) && !empty($fvm_settings['css']['css_ignore_min'])) {
|
1656 |
+
$arr = fvm_string_toarray($fvm_settings['css']['css_ignore_min']);
|
1657 |
+
if(is_array($arr) && count($arr) > 0) {
|
1658 |
+
foreach ($arr as $e) {
|
1659 |
+
if(stripos($url, $e) !== false) {
|
1660 |
+
$min = false;
|
1661 |
+
break;
|
1662 |
+
}
|
1663 |
+
}
|
1664 |
+
}
|
1665 |
+
}
|
1666 |
+
|
1667 |
# filtering
|
1668 |
+
$css = fvm_ensure_utf8($css);
|
1669 |
$css = str_ireplace('@charset "UTF-8";', '', $css);
|
1670 |
|
1671 |
# remove query strings from fonts
|
1681 |
$css = preg_replace("/url\(\s*['\"]?(?!data:)(?!http)(?![\/'\"#])(.+?)['\"]?\s*\)/ui", "url(".dirname($url)."/$1)", $css);
|
1682 |
}
|
1683 |
|
|
|
|
|
1684 |
# minify string with relative urls
|
1685 |
+
if($min === true) {
|
1686 |
+
$css = fvm_minify_css_string($css, $url);
|
1687 |
}
|
1688 |
|
1689 |
# add font-display block for all font faces
|
1690 |
# https://developers.google.com/web/updates/2016/02/font-display
|
1691 |
+
$css = preg_replace_callback('/(?:@font-face)\s*{(?<value>[^}]+)}/i',
|
1692 |
+
function ($matches) {
|
1693 |
+
if ( preg_match('/font-display:\s*(?<swap_value>\w*);?/i', $matches['value'], $attribute)) {
|
1694 |
+
return 'swap' === strtolower($attribute['swap_value']) ? $matches[0] : str_replace($attribute['swap_value'], 'swap', $matches[0]);
|
1695 |
+
} else {
|
1696 |
+
$swap = "font-display:swap;{$matches['value']}";
|
|
|
|
|
|
|
|
|
1697 |
}
|
1698 |
+
return str_replace( $matches['value'], $swap, $matches[0] );
|
1699 |
+
},
|
1700 |
+
$css
|
1701 |
+
);
|
1702 |
|
1703 |
# make relative urls when possible
|
1704 |
+
|
|
|
1705 |
# get root url, preserve subdirectories
|
1706 |
if(isset($fvm_urls['wp_site_url']) && !empty($fvm_urls['wp_site_url'])) {
|
1707 |
|
1714 |
|
1715 |
# adjust paths
|
1716 |
$bgimgs = array();
|
1717 |
+
preg_match_all ('/url\s*\((\s*[\'"]?(http:|https:|\/\/).+[\'"]?\s*)\)/Uui', $css, $bgimgs);
|
1718 |
if(isset($bgimgs[1]) && is_array($bgimgs[1])) {
|
1719 |
foreach($bgimgs[1] as $img) {
|
1720 |
+
|
1721 |
+
# normalize
|
1722 |
+
$newimg = fvm_normalize_url($img);
|
1723 |
+
if($newimg != $img) { $css = str_replace($img, $newimg, $css); $img = $newimg; }
|
1724 |
+
|
1725 |
+
# process
|
1726 |
if(substr($img, 0, strlen($use_url)) == $use_url) {
|
1727 |
$pos = strpos($img, $use_url);
|
1728 |
if ($pos !== false) {
|
1729 |
+
|
1730 |
+
# relative path image
|
1731 |
+
$relimg = '/' . ltrim(substr_replace($img, '', $pos, strlen($use_url)), '/');
|
1732 |
+
|
1733 |
+
# replace url
|
1734 |
$css = str_replace($img, $relimg, $css);
|
1735 |
+
|
1736 |
}
|
1737 |
}
|
1738 |
}
|
1739 |
}
|
1740 |
+
|
1741 |
+
# remove empty url()
|
1742 |
+
$css = preg_replace('/url\s*\(\s*[\'"]?\s*[\'"]?\)/Uui', 'none', $css);
|
1743 |
+
|
1744 |
+
# relative paths
|
1745 |
+
$css = str_replace('https://'.$fvm_urls['wp_domain'], '', $css);
|
1746 |
+
$css = str_replace('http://'.$fvm_urls['wp_domain'], '', $css);
|
1747 |
+
$css = str_replace('//'.$fvm_urls['wp_domain'], '', $css);
|
1748 |
+
|
1749 |
+
}
|
1750 |
+
|
1751 |
+
# simplify font face
|
1752 |
+
$arr = fvm_simplify_fontface($css);
|
1753 |
+
if($arr !== false && is_array($arr)) {
|
1754 |
+
$css = str_replace($arr['before'], $arr['after'], $css);
|
1755 |
}
|
1756 |
|
1757 |
# return css
|
1759 |
|
1760 |
}
|
1761 |
|
1762 |
+
return false;
|
1763 |
}
|
1764 |
|
1765 |
|
1779 |
global $fvm_settings;
|
1780 |
|
1781 |
# filtering
|
1782 |
+
$js = fvm_ensure_utf8($js);
|
1783 |
|
1784 |
# remove sourceMappingURL
|
1785 |
$js = preg_replace('/(\/\/\s*[#]\s*sourceMappingURL\s*[=]\s*)([a-zA-Z0-9-_\.\/]+)(\.map)/ui', '', $js);
|
1836 |
|
1837 |
# try catch wrapper for merged javascript
|
1838 |
function fvm_try_catch_wrap($js, $href=null) {
|
1839 |
+
$loc = ''; if(isset($href)) { $loc = '[ File: '. $href . ' ] '; }
|
1840 |
+
return 'try{'. PHP_EOL . $js . PHP_EOL . '}catch(e){console.error("An error has occurred. '.$loc.'[ "+e.stack+" ]");}';
|
1841 |
}
|
1842 |
|
1843 |
|
1905 |
}
|
1906 |
|
1907 |
|
1908 |
+
# try to open the file from the disk, before downloading
|
1909 |
+
function fvm_maybe_download($url) {
|
|
|
1910 |
|
1911 |
+
# must have
|
1912 |
+
if(is_null($url) || empty($url)) { return false; }
|
1913 |
+
|
1914 |
+
# get domain
|
1915 |
+
global $fvm_urls;
|
1916 |
+
|
1917 |
+
# check if we can open the file locally first
|
1918 |
+
if (stripos($url, $fvm_urls['wp_domain']) !== false && defined('ABSPATH') && !empty('ABSPATH')) {
|
1919 |
+
|
1920 |
+
# file path + windows compatibility
|
1921 |
+
$f = strtok(str_replace('/', DIRECTORY_SEPARATOR, str_replace(rtrim($fvm_urls['wp_site_url'], '/'), rtrim(ABSPATH, '/'), $url)), '?');
|
|
|
|
|
|
|
|
|
|
|
|
|
1922 |
|
1923 |
+
# did it work?
|
1924 |
+
if (file_exists($f)) {
|
1925 |
+
return array('content'=>file_get_contents($f), 'src'=>'Disk');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1926 |
}
|
1927 |
}
|
1928 |
+
|
1929 |
+
# fallback to downloading
|
1930 |
|
1931 |
+
# this useragent is needed for google fonts (woff files only + hinted fonts)
|
1932 |
+
$uagent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Safari/537.36 Edge/13.10586';
|
1933 |
+
|
1934 |
+
# fetch via wordpress functions
|
1935 |
+
$response = wp_remote_get($url, array('user-agent'=>$uagent, 'timeout' => 7, 'httpversion' => '1.1', 'sslverify'=>false));
|
1936 |
+
if ( is_wp_error( $response ) ) {
|
1937 |
+
$error_message = $response->get_error_message();
|
1938 |
+
return array('error'=>"Something went wrong: $error_message / $url");
|
1939 |
+
} else {
|
1940 |
+
return array('content'=>wp_remote_retrieve_body($response), 'src'=>'Web');
|
1941 |
+
}
|
1942 |
}
|
1943 |
|
1944 |
|
1959 |
return $html;
|
1960 |
}
|
1961 |
|
1962 |
+
# add lazy load library
|
1963 |
+
function fvm_add_delay_scripts_logic($html) {
|
1964 |
+
|
1965 |
+
# based on v2.0.0: https://github.com/shinsenter/defer.js
|
1966 |
+
# delay to interaction
|
1967 |
+
$scripts = <<<'EOF'
|
1968 |
+
<script type='text/javascript' id='fvm-delayjs' data-cfasync='false'>
|
1969 |
+
!function(k,e,x){function r(d,a,g,b){return b=(a?e.getElementById(a):t)||e.createElement(d||"SCRIPT"),a&&(b.id=a),g&&(b.onload=g),b}function u(d){f(function(a){a=[].slice.call(e.querySelectorAll(d));(function v(b,c){if(b=a.shift()){b.parentNode.removeChild(b);var l=b,m,n=void 0;var p=r(l.nodeName);var q=0;for(m=l.attributes;q<m.length;q++)"type"!=(n=m[q]).name&&p.setAttribute(n.name,n.value);(c=(p.text=l.text,p)).src&&!c.hasAttribute("async")?(c.onload=c.onerror=v,e.head.appendChild(c)):(e.head.appendChild(c),
|
1970 |
+
v())}})()})}var f,t,h=[],w=/p/.test(e.readyState);Function();(f=function(d,a){w?x(d,a):h.push(d,a)}).all=u;f.js=function(d,a,g,b){f(function(c){(c=r(t,a,b)).src=d;e.head.appendChild(c)},g)};k.addEventListener("onpageshow"in k?"pageshow":"load",function(){for(w=!u();h[0];)f(h.shift(),h.shift())});k.Defer=f}(this,document,setTimeout);
|
1971 |
+
const userInteractionEvents=["mouseover","keydown","touchstart","touchmove","wheel"];userInteractionEvents.forEach(function(event){window.addEventListener(event,triggerScriptLoader,{passive:!0})});function triggerScriptLoader(){fvmloadscripts();userInteractionEvents.forEach(function(event){window.removeEventListener(event,triggerScriptLoader,{passive:!0})})}function fvmloadscripts(){Defer.all('script[type="fvm-script-delay"]')};
|
1972 |
+
</script>
|
1973 |
+
EOF;
|
1974 |
+
|
1975 |
+
# add code
|
1976 |
+
return str_replace('<!-- h_footer_fvm_scripts -->', '<!-- h_footer_fvm_scripts -->' . $scripts, $html);
|
1977 |
+
|
1978 |
+
}
|
1979 |
+
|
1980 |
+
|
1981 |
+
# get the domain name
|
1982 |
+
function fvm_get_scheme() {
|
1983 |
+
if(isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') { return 'https'; }
|
1984 |
+
if(isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == 443) { return 'https'; }
|
1985 |
+
if(isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') { return 'https'; }
|
1986 |
+
return 'http';
|
1987 |
+
}
|
1988 |
|
1989 |
# get the domain name
|
1990 |
function fvm_get_domain() {
|
1991 |
+
if (function_exists('site_url')) {
|
1992 |
+
$parse = parse_url(site_url());
|
1993 |
+
return $parse['host'];
|
1994 |
+
} elseif(isset($_SERVER['SERVER_NAME']) && !empty($_SERVER['SERVER_NAME'])) {
|
1995 |
return $_SERVER['SERVER_NAME'];
|
1996 |
} elseif (isset($_SERVER['HTTP_HOST']) && !empty($_SERVER['HTTP_HOST'])) {
|
1997 |
return $_SERVER['HTTP_HOST'];
|
|
|
|
|
1998 |
} else {
|
1999 |
return false;
|
2000 |
}
|
2001 |
}
|
2002 |
|
|
|
2003 |
# get the settings file path, current domain name, and uri path without query strings
|
2004 |
+
function fvm_get_uripath($full=null) {
|
2005 |
if (isset($_SERVER['REQUEST_URI']) && !empty($_SERVER['REQUEST_URI'])) {
|
2006 |
+
|
2007 |
+
# full or no query string
|
2008 |
+
if(!is_null($full)) {
|
2009 |
+
$current_uri = trim($_SERVER['REQUEST_URI']);
|
2010 |
+
} else {
|
2011 |
+
$current_uri = strtok($_SERVER['REQUEST_URI'], '?');
|
2012 |
+
}
|
2013 |
+
|
2014 |
+
# filter
|
2015 |
$current_uri = str_replace('//', '/', str_replace('..', '', preg_replace( '/[ <>\'\"\r\n\t\(\)]/', '', $current_uri)));
|
2016 |
return $current_uri;
|
2017 |
} else {
|
inc/frontend.php
CHANGED
@@ -34,7 +34,7 @@ include_once($fvm_var_inc_lib_mm . 'path-converter' . DIRECTORY_SEPARATOR . 'src
|
|
34 |
|
35 |
# start buffering before template
|
36 |
function fvm_start_buffer() {
|
37 |
-
if(
|
38 |
ob_start('fvm_process_page', 0, PHP_OUTPUT_HANDLER_REMOVABLE);
|
39 |
}
|
40 |
}
|
@@ -45,96 +45,111 @@ function fvm_process_page($html) {
|
|
45 |
# get globals
|
46 |
global $fvm_settings, $fvm_cache_paths, $fvm_urls;
|
47 |
|
48 |
-
#
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
54 |
}
|
55 |
-
|
|
|
|
|
|
|
|
|
|
|
56 |
# defaults
|
57 |
-
$
|
58 |
-
$
|
59 |
-
$
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
65 |
|
66 |
-
#
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
}
|
72 |
|
73 |
-
|
74 |
-
|
75 |
-
$allpreloads = array();
|
76 |
-
foreach($html->find('link[rel=preload]') as $tag) {
|
77 |
|
78 |
-
#
|
79 |
-
$
|
80 |
-
if(isset($tag->importance)) {
|
81 |
-
$importance = $tag->importance;
|
82 |
-
} else {
|
83 |
-
$tag->importance = 'auto';
|
84 |
-
}
|
85 |
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
90 |
}
|
91 |
|
92 |
-
# collect, group by importance and remove
|
93 |
-
$allpreloads[$importance][] = $tag->outertext;
|
94 |
-
$tag->outertext = '';
|
95 |
-
}
|
96 |
-
|
97 |
-
|
98 |
-
# process css, if not disabled
|
99 |
-
if(isset($fvm_settings['css']['enable']) && $fvm_settings['css']['enable'] == true) {
|
100 |
-
|
101 |
-
# defaults
|
102 |
-
$fvm_styles = array();
|
103 |
-
$fvm_styles_log = array();
|
104 |
-
$critical_path = array();
|
105 |
-
$enable_css_minification = true;
|
106 |
|
107 |
-
#
|
108 |
-
$
|
109 |
-
foreach($html->find('script link[rel=stylesheet], script style, noscript style, noscript link[rel=stylesheet], comment') as $element) {
|
110 |
-
$excl[] = $element->outertext;
|
111 |
-
}
|
112 |
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
if(!in_array($element->outertext, $excl)) {
|
117 |
-
$allcss[] = $element;
|
118 |
-
}
|
119 |
-
}
|
120 |
-
|
121 |
-
# merge and process
|
122 |
-
foreach($allcss as $k=>$tag) {
|
123 |
-
|
124 |
-
# ignore list, leave these alone
|
125 |
-
if(isset($tag->href) && isset($fvm_settings['css']['ignore']) && !empty($fvm_settings['css']['ignore'])) {
|
126 |
$arr = fvm_string_toarray($fvm_settings['css']['ignore']);
|
127 |
if(is_array($arr) && count($arr) > 0) {
|
128 |
foreach ($arr as $e) {
|
129 |
if(stripos($tag->href, $e) !== false) {
|
|
|
130 |
continue 2;
|
131 |
}
|
132 |
}
|
133 |
}
|
134 |
-
}
|
135 |
-
|
136 |
-
#
|
137 |
-
if(isset($
|
138 |
$arr = fvm_string_toarray($fvm_settings['css']['remove']);
|
139 |
if(is_array($arr) && count($arr) > 0) {
|
140 |
foreach ($arr as $e) {
|
@@ -147,368 +162,358 @@ function fvm_process_page($html) {
|
|
147 |
}
|
148 |
}
|
149 |
|
150 |
-
#
|
151 |
-
if(isset($
|
152 |
-
$arr = array('/fonts.googleapis.com', '/animate.css', '/animate.min.css', '/icomoon.css', '/animations/', '/eicons/css/', 'font-awesome', 'fontawesome', '/flag-icon.min.css', '/fonts.css', '/pe-icon-7-stroke.css', '/fontello.css', '/dashicons.min.css');
|
153 |
-
if(is_array($arr) && count($arr) > 0) {
|
154 |
-
foreach ($arr as $e) {
|
155 |
-
if(stripos($tag->href, $e) !== false) {
|
156 |
-
$tag->media = 'fonts';
|
157 |
-
break;
|
158 |
-
}
|
159 |
-
}
|
160 |
-
}
|
161 |
-
}
|
162 |
-
|
163 |
-
|
164 |
-
# normalize mediatypes
|
165 |
-
$media = 'all';
|
166 |
-
if(isset($tag->media)) {
|
167 |
-
$media = $tag->media;
|
168 |
-
if ($media == 'screen' || $media == 'screen, print' || empty($media) || is_null($media) || $media == false) {
|
169 |
-
$media = 'all';
|
170 |
-
}
|
171 |
-
}
|
172 |
-
|
173 |
-
# remove print mediatypes
|
174 |
-
if(isset($fvm_settings['css']['noprint']) && $fvm_settings['css']['noprint'] == true && $media == 'print') {
|
175 |
-
$tag->outertext = '';
|
176 |
-
unset($allcss[$k]);
|
177 |
-
continue;
|
178 |
-
}
|
179 |
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
# default
|
184 |
-
$css = '';
|
185 |
-
|
186 |
-
# make sure we have a complete url
|
187 |
-
$href = fvm_normalize_url($tag->href, $fvm_urls['wp_domain'], $fvm_urls['wp_site_url']);
|
188 |
-
|
189 |
-
# get minification settings for files
|
190 |
-
if(isset($fvm_settings['css']['min_disable']) && $fvm_settings['css']['min_disable'] == '1') {
|
191 |
-
$enable_css_minification = false;
|
192 |
-
}
|
193 |
-
|
194 |
-
# force minification on google fonts
|
195 |
-
if(stripos($href, 'fonts.googleapis.com') !== false) {
|
196 |
-
$enable_css_minification = true;
|
197 |
-
}
|
198 |
|
199 |
-
|
200 |
-
$tkey = hash('sha1', $href);
|
201 |
-
$css = fvm_get_transient($tkey);
|
202 |
-
if ($css === false) {
|
203 |
|
204 |
-
#
|
205 |
-
$
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
$css = $ddl['content'];
|
213 |
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
|
|
|
|
|
|
219 |
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
$fs = strlen($css);
|
228 |
-
$ur = str_replace($fvm_urls['wp_site_url'], '', $href);
|
229 |
-
$tkey_meta = array('fs'=>$fs, 'url'=>str_replace($fvm_cache_paths['cache_url_min'].'/', '', $ur), 'mt'=>$media);
|
230 |
-
|
231 |
-
# save
|
232 |
-
fvm_set_transient(array('uid'=>$tkey, 'date'=>$tvers, 'type'=>'css', 'content'=>$css, 'meta'=>$tkey_meta));
|
233 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
234 |
}
|
235 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
236 |
}
|
|
|
|
|
|
|
|
|
|
|
237 |
|
|
|
|
|
238 |
|
239 |
-
|
240 |
-
if($css !== false) {
|
241 |
|
242 |
-
#
|
243 |
-
if(isset($fvm_settings['css']['
|
244 |
-
$
|
245 |
-
$
|
246 |
-
|
247 |
-
continue;
|
248 |
} else {
|
249 |
-
|
250 |
-
|
251 |
-
|
|
|
|
|
252 |
$tag->outertext = '';
|
253 |
unset($allcss[$k]);
|
254 |
continue;
|
|
|
|
|
255 |
}
|
256 |
-
|
257 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
258 |
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
continue;
|
264 |
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
if(isset($fvm_settings['css']['min_disable']) && $fvm_settings['css']['min_disable'] == true) {
|
278 |
-
$enable_css_minification = true;
|
279 |
-
}
|
280 |
-
|
281 |
-
# minify inline CSS
|
282 |
-
$css = $tag->innertext;
|
283 |
-
if($enable_css_minification) {
|
284 |
-
$css = fvm_minify_css_string($css);
|
285 |
-
}
|
286 |
-
|
287 |
-
# handle import rules
|
288 |
-
$css = fvm_replace_css_imports($css);
|
289 |
-
|
290 |
-
# remove fonts and icons and collect for later
|
291 |
-
if(isset($fvm_settings['css']['fonts']) && $fvm_settings['css']['fonts'] == true) {
|
292 |
-
$mff = array();
|
293 |
-
preg_match_all('/(\@font-face)([^}]+)(\})/', $css, $mff);
|
294 |
-
if(isset($mff[0]) && is_array($mff[0])) {
|
295 |
-
foreach($mff[0] as $ff) {
|
296 |
-
$css = str_replace($ff, '', $css);
|
297 |
-
$lp_css_last_ff_inline.= $ff . PHP_EOL;
|
298 |
}
|
299 |
}
|
300 |
-
}
|
301 |
-
|
302 |
-
# add cdn support
|
303 |
-
if(isset($fvm_settings['cdn']['enable']) && $fvm_settings['cdn']['enable'] == true &&
|
304 |
-
isset($fvm_settings['cdn']['domain']) && !empty($fvm_settings['cdn']['domain'])) {
|
305 |
-
if(isset($fvm_settings['cdn']['cssok']) && $fvm_settings['cdn']['cssok'] == true) {
|
306 |
-
|
307 |
-
# scheme + site url
|
308 |
-
$fcdn = str_replace($fvm_urls['wp_domain'], $fvm_settings['cdn']['domain'], $fvm_urls['wp_site_url']);
|
309 |
-
|
310 |
-
# replacements
|
311 |
-
$css = str_ireplace('url(/wp-content/', 'url('.$fcdn.'/wp-content/', $css);
|
312 |
-
$css = str_ireplace('url("/wp-content/', 'url("'.$fcdn.'/wp-content/', $css);
|
313 |
-
$css = str_ireplace('url(\'/wp-content/', 'url(\''.$fcdn.'/wp-content/', $css);
|
314 |
|
|
|
|
|
|
|
|
|
|
|
|
|
315 |
}
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
}
|
325 |
-
|
326 |
-
# trim code
|
327 |
-
$css = trim($css);
|
328 |
-
|
329 |
-
# decide what to do with the inlined css
|
330 |
-
if(empty($css)) {
|
331 |
-
# delete empty style tags
|
332 |
-
$tag->outertext = '';
|
333 |
-
unset($allcss[$k]);
|
334 |
-
continue;
|
335 |
-
} else {
|
336 |
-
# process inlined styles
|
337 |
-
$tag->innertext = $css;
|
338 |
unset($allcss[$k]);
|
339 |
-
|
340 |
}
|
341 |
-
|
342 |
}
|
343 |
-
|
344 |
}
|
|
|
|
|
345 |
|
346 |
-
#
|
347 |
-
if(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
348 |
|
349 |
-
#
|
350 |
-
$
|
351 |
-
$lp_css_last_ff = '';
|
352 |
|
353 |
-
#
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
if($mediatype == 'fonts') {
|
358 |
-
$lp_css_last = $fvm_styles['fonts'];
|
359 |
-
continue;
|
360 |
-
}
|
361 |
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
$mff = array();
|
371 |
-
preg_match_all('/(\@font-face)([^}]+)(\})/', $file_css_code, $mff);
|
372 |
-
if(isset($mff[0]) && is_array($mff[0])) {
|
373 |
-
foreach($mff[0] as $ff) {
|
374 |
-
$file_css_code = str_replace($ff, '', $file_css_code);
|
375 |
-
$lp_css_last_ff.= $ff . PHP_EOL;
|
376 |
-
}
|
377 |
-
}
|
378 |
-
}
|
379 |
-
|
380 |
-
# add cdn support
|
381 |
-
if(isset($fvm_settings['cdn']['enable']) && $fvm_settings['cdn']['enable'] == true &&
|
382 |
-
isset($fvm_settings['cdn']['domain']) && !empty($fvm_settings['cdn']['domain'])) {
|
383 |
-
if(isset($fvm_settings['cdn']['cssok']) && $fvm_settings['cdn']['cssok'] == true) {
|
384 |
-
$file_css_url = str_replace('//'.$fvm_urls['wp_domain'], '//'.$fvm_settings['cdn']['domain'], $file_css_url);
|
385 |
-
}
|
386 |
-
}
|
387 |
-
|
388 |
-
# generate cache file
|
389 |
-
clearstatcache();
|
390 |
-
if (!file_exists($file_css)) {
|
391 |
-
|
392 |
-
# prepare log
|
393 |
-
$log = (array) array_values($fvm_styles_log[$mediatype]);
|
394 |
-
$log_meta = array('loc'=>home_url(add_query_arg(NULL, NULL)), 'fl'=>$file_css_url, 'mt'=>$mediatype);
|
395 |
-
|
396 |
-
# generate cache, write log
|
397 |
-
if(!empty($file_css_code)) {
|
398 |
-
fvm_save_log(array('uid'=>$file_css_url, 'date'=>$now, 'type'=>'css', 'meta'=>$log_meta, 'content'=>$log));
|
399 |
-
fvm_save_file($file_css, $file_css_code);
|
400 |
-
}
|
401 |
-
|
402 |
-
}
|
403 |
-
|
404 |
-
# if file exists
|
405 |
-
clearstatcache();
|
406 |
-
if (file_exists($file_css)) {
|
407 |
-
|
408 |
-
# preload and save for html implementation (with priority order prefix)
|
409 |
-
if((!isset($fvm_settings['css']['nopreload']) || (isset($fvm_settings['css']['nopreload']) && $fvm_settings['css']['nopreload'] != true)) && (!isset($fvm_settings['css']['inline-all']) || (isset($fvm_settings['css']['inline-all']) && $fvm_settings['css']['inline-all'] != true))) {
|
410 |
-
$allpreloads['high'][] = '<link rel="preload" href="'.$file_css_url.'" as="style" media="'.$mediatype.'" importance="high" />';
|
411 |
-
}
|
412 |
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
|
|
|
|
|
|
|
|
421 |
}
|
422 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
423 |
|
424 |
-
#
|
425 |
-
|
|
|
|
|
|
|
|
|
426 |
|
427 |
-
#
|
428 |
-
$
|
|
|
|
|
|
|
429 |
|
430 |
-
#
|
431 |
-
$
|
432 |
-
$css_uid = $tvers.'-'.hash('sha1', $file_css_code);
|
433 |
-
$file_css = $fvm_cache_paths['cache_dir_min'] . DIRECTORY_SEPARATOR . $css_uid.'.min.css';
|
434 |
-
$file_css_url = $fvm_cache_paths['cache_url_min'].'/'.$css_uid.'.min.css';
|
435 |
|
436 |
-
#
|
437 |
-
if(isset($fvm_settings['cdn']['
|
438 |
-
|
439 |
-
if(isset($fvm_settings['cdn']['cssok']) && $fvm_settings['cdn']['cssok'] == true) {
|
440 |
-
$file_css_url = str_replace('//'.$fvm_urls['wp_domain'], '//'.$fvm_settings['cdn']['domain'], $file_css_url);
|
441 |
-
}
|
442 |
}
|
|
|
|
|
|
|
443 |
|
444 |
-
|
445 |
-
|
446 |
-
if (!file_exists($file_css)) {
|
447 |
|
448 |
-
#
|
449 |
-
$
|
450 |
-
|
|
|
|
|
451 |
|
452 |
-
|
453 |
-
if(!empty($file_css_code)) {
|
454 |
-
fvm_save_log(array('uid'=>$file_css_url, 'date'=>$now, 'type'=>'css', 'meta'=>$log_meta, 'content'=>$log));
|
455 |
-
fvm_save_file($file_css, $file_css_code);
|
456 |
-
}
|
457 |
-
}
|
458 |
-
|
459 |
-
# if file exists
|
460 |
-
clearstatcache();
|
461 |
-
if (file_exists($file_css)) {
|
462 |
|
463 |
-
#
|
464 |
-
$htmlcssheader[
|
465 |
|
466 |
-
}
|
467 |
-
|
468 |
-
}
|
469 |
-
|
470 |
}
|
471 |
}
|
472 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
473 |
|
474 |
-
#
|
475 |
-
$
|
476 |
-
|
477 |
|
478 |
-
#
|
479 |
-
|
480 |
-
|
481 |
-
|
482 |
-
|
483 |
-
|
484 |
-
$
|
485 |
-
|
486 |
-
$scripts_header = array();
|
487 |
-
$scripts_footer = array();
|
488 |
|
489 |
-
|
490 |
-
|
491 |
-
foreach($
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
|
496 |
-
|
497 |
-
|
498 |
-
|
499 |
-
#
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
504 |
}
|
505 |
|
506 |
-
# remove js
|
507 |
-
if(isset($
|
508 |
$arr = fvm_string_toarray($fvm_settings['js']['remove']);
|
509 |
if(is_array($arr) && count($arr) > 0) {
|
510 |
-
foreach ($arr as $
|
511 |
-
if(stripos($tag->
|
512 |
$tag->outertext = '';
|
513 |
unset($allscripts[$k]);
|
514 |
continue 2;
|
@@ -517,490 +522,499 @@ function fvm_process_page($html) {
|
|
517 |
}
|
518 |
}
|
519 |
|
520 |
-
|
521 |
-
#
|
522 |
-
if(
|
523 |
-
|
524 |
-
|
525 |
-
|
526 |
-
|
527 |
-
|
528 |
-
|
529 |
-
|
530 |
-
|
531 |
-
|
532 |
-
|
533 |
-
|
534 |
-
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
-
|
539 |
-
|
540 |
-
|
541 |
-
|
542 |
-
|
543 |
-
|
544 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
545 |
}
|
546 |
-
}
|
547 |
}
|
548 |
}
|
549 |
}
|
550 |
|
551 |
-
#
|
552 |
-
if(isset($fvm_settings['js']['
|
553 |
-
$arr = fvm_string_toarray($fvm_settings['js']['
|
554 |
if(is_array($arr) && count($arr) > 0) {
|
555 |
-
foreach ($arr as $
|
556 |
-
if(stripos($
|
557 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
558 |
}
|
559 |
}
|
560 |
}
|
561 |
}
|
562 |
-
|
563 |
|
564 |
-
#
|
565 |
-
$tag->
|
566 |
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
-
|
573 |
-
|
574 |
-
# process js files
|
575 |
-
if(isset($tag->src)) {
|
576 |
-
|
577 |
-
# make sure we have a complete url
|
578 |
-
$href = fvm_normalize_url($tag->src, $fvm_urls['wp_domain'], $fvm_urls['wp_site_url']);
|
579 |
-
|
580 |
-
# upgrade jQuery library and jQuery migrate to version 3
|
581 |
-
if(isset($fvm_settings['js']['jqupgrade']) && $fvm_settings['js']['jqupgrade'] == true) {
|
582 |
-
# jquery 3
|
583 |
-
if(stripos($tag->src, '/jquery.js') !== false || stripos($tag->src, '/jquery.min.js') !== false) {
|
584 |
-
$href = 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js';
|
585 |
}
|
586 |
-
|
587 |
-
|
588 |
-
|
589 |
-
|
590 |
-
|
591 |
-
|
592 |
-
$enable_js_minification = false;
|
593 |
-
}
|
594 |
-
|
595 |
-
# ignore list, leave these alone
|
596 |
-
if(isset($fvm_settings['js']['ignore']) && !empty($fvm_settings['js']['ignore'])) {
|
597 |
-
$arr = fvm_string_toarray($fvm_settings['js']['ignore']);
|
598 |
-
if(is_array($arr) && count($arr) > 0) {
|
599 |
-
foreach ($arr as $e) {
|
600 |
-
if(stripos($tag->src, $e) !== false) {
|
601 |
-
continue 2;
|
602 |
-
}
|
603 |
-
}
|
604 |
}
|
605 |
-
|
|
|
|
|
|
|
|
|
|
|
606 |
|
607 |
-
|
608 |
-
|
609 |
-
|
610 |
-
|
611 |
-
|
612 |
-
|
613 |
-
|
614 |
-
foreach ($arr as $b) {
|
615 |
-
if(stripos($tag->src, $b) !== false) {
|
616 |
-
|
617 |
-
# get all extra attributes into $rem
|
618 |
-
$rem = '';
|
619 |
-
foreach($tag->getAllAttributes() as $k=>$v){
|
620 |
-
$k = trim($k); $v = trim($v);
|
621 |
-
if($k != 'async' && $k != 'defer' && $k != 'src' && $k != 'type') {
|
622 |
-
$rem.= "b.setAttribute('$k','$v');";
|
623 |
-
}
|
624 |
-
}
|
625 |
-
|
626 |
-
# defer attribute? (async is always by default)
|
627 |
-
if(isset($tag->defer)) {
|
628 |
-
$rem.= 'b.async=false;';
|
629 |
-
}
|
630 |
-
|
631 |
-
# generate and set delayed script tag
|
632 |
-
$tag->outertext = "<script data-cfasync='false'>".'if(fvmuag()){window.addEventListener("load",function(){var c=setTimeout(b,5E3),d=["mouseover","keydown","touchmove","touchstart"];d.forEach(function(a){window.addEventListener(a,e,{passive:!0})});function e(){b();clearTimeout(c);d.forEach(function(a){window.removeEventListener(a,e,{passive:!0})})}function b(){'."(function(a){var b=a.createElement('script'),c=a.scripts[0];b.src='".trim($tag->src)."';".$rem."c.parentNode.insertBefore(b,c);}(document));".'};});}'."</script>";
|
633 |
-
unset($allscripts[$k]);
|
634 |
-
continue 2;
|
635 |
-
|
636 |
-
}
|
637 |
-
}
|
638 |
-
}
|
639 |
-
}
|
640 |
-
}
|
641 |
-
}
|
642 |
|
643 |
-
# render blocking
|
644 |
if(isset($fvm_settings['js']['merge_header']) && !empty($fvm_settings['js']['merge_header'])) {
|
645 |
$arr = fvm_string_toarray($fvm_settings['js']['merge_header']);
|
646 |
if(is_array($arr) && count($arr) > 0) {
|
647 |
-
foreach ($arr as $
|
648 |
-
if(stripos($
|
649 |
|
650 |
-
# download
|
651 |
-
$
|
652 |
-
$js
|
653 |
-
if ($js === false) {
|
654 |
-
|
655 |
-
# open or download file, get contents
|
656 |
-
$ddl = array();
|
657 |
-
$ddl = fvm_maybe_download($href);
|
658 |
|
659 |
-
#
|
660 |
-
|
661 |
-
|
662 |
-
|
663 |
-
|
664 |
-
|
665 |
-
# minify, save and wrap
|
666 |
-
$js = fvm_maybe_minify_js($js, $href, $enable_js_minification);
|
667 |
-
|
668 |
-
# quick integrity check
|
669 |
-
if(!empty($js) && $js !== false) {
|
670 |
-
|
671 |
-
# try catch
|
672 |
-
$js = fvm_try_catch_wrap($js, $href);
|
673 |
-
|
674 |
-
# developers filter
|
675 |
-
$js = apply_filters( 'fvm_after_download_and_minify_code', $js, 'js');
|
676 |
-
|
677 |
-
# execution time in ms, size in bytes
|
678 |
-
$fs = strlen($js);
|
679 |
-
$ur = str_replace($fvm_urls['wp_site_url'], '', $href);
|
680 |
-
$tkey_meta = array('fs'=>$fs, 'url'=>str_replace($fvm_cache_paths['cache_url_min'].'/', '', $ur));
|
681 |
-
|
682 |
-
# save
|
683 |
-
fvm_set_transient(array('uid'=>$tkey, 'date'=>$tvers, 'type'=>'js', 'content'=>$js, 'meta'=>$tkey_meta));
|
684 |
-
|
685 |
-
}
|
686 |
}
|
687 |
-
}
|
688 |
-
|
689 |
-
# processed successfully?
|
690 |
-
if ($js !== false) {
|
691 |
-
|
692 |
-
# collect and mark as done for html removal
|
693 |
-
$scripts_header[$tkey] = $js;
|
694 |
-
$scripts_header_log[$tkey] = $tkey;
|
695 |
|
696 |
-
#
|
697 |
-
$tag->
|
698 |
-
unset($
|
699 |
-
|
700 |
-
|
701 |
-
|
702 |
-
|
703 |
-
|
704 |
-
|
705 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
706 |
unset($allscripts[$k]);
|
707 |
continue 2;
|
708 |
|
709 |
}
|
710 |
-
|
711 |
}
|
712 |
}
|
713 |
}
|
714 |
}
|
715 |
-
|
716 |
-
|
717 |
-
# merge and defer scripts
|
718 |
if(isset($fvm_settings['js']['merge_defer']) && !empty($fvm_settings['js']['merge_defer'])) {
|
719 |
$arr = fvm_string_toarray($fvm_settings['js']['merge_defer']);
|
720 |
if(is_array($arr) && count($arr) > 0) {
|
721 |
-
foreach ($arr as $
|
722 |
-
if(stripos($
|
723 |
-
|
724 |
-
# download, minify, cache
|
725 |
-
$tkey = hash('sha1', $href);
|
726 |
-
$js = fvm_get_transient($tkey);
|
727 |
-
if ($js === false) {
|
728 |
-
|
729 |
-
# open or download file, get contents
|
730 |
-
$ddl = array();
|
731 |
-
$ddl = fvm_maybe_download($href);
|
732 |
|
733 |
-
|
734 |
-
|
735 |
-
|
736 |
-
# contents
|
737 |
-
$js = $ddl['content'];
|
738 |
-
|
739 |
-
# minify, save and wrap
|
740 |
-
$js = fvm_maybe_minify_js($js, $href, $enable_js_minification);
|
741 |
-
|
742 |
-
# quick integrity check
|
743 |
-
if(!empty($js) && $js !== false) {
|
744 |
-
|
745 |
-
# try catch
|
746 |
-
$js = fvm_try_catch_wrap($js, $href);
|
747 |
-
|
748 |
-
# developers filter
|
749 |
-
$js = apply_filters( 'fvm_after_download_and_minify_code', $js, 'js');
|
750 |
-
|
751 |
-
# execution time in ms, size in bytes
|
752 |
-
$fs = strlen($js);
|
753 |
-
$ur = str_replace($fvm_urls['wp_site_url'], '', $href);
|
754 |
-
$tkey_meta = array('fs'=>$fs, 'url'=>str_replace($fvm_cache_paths['cache_url_min'].'/', '', $ur));
|
755 |
-
|
756 |
-
# save
|
757 |
-
fvm_set_transient(array('uid'=>$tkey, 'date'=>$tvers, 'type'=>'js', 'content'=>$js, 'meta'=>$tkey_meta));
|
758 |
-
|
759 |
-
}
|
760 |
-
}
|
761 |
-
}
|
762 |
|
763 |
-
|
764 |
-
|
765 |
-
|
766 |
-
# collect and mark as done for html removal
|
767 |
-
$scripts_footer[$tkey] = $js;
|
768 |
-
$scripts_footer_log[$tkey] = $tkey;
|
769 |
|
770 |
-
#
|
771 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
772 |
unset($allscripts[$k]);
|
773 |
continue 2;
|
774 |
|
775 |
}
|
776 |
-
|
777 |
}
|
778 |
}
|
779 |
}
|
780 |
}
|
781 |
-
|
782 |
-
|
783 |
-
|
|
|
|
|
|
|
|
|
784 |
}
|
785 |
-
|
786 |
-
|
787 |
-
|
788 |
-
|
789 |
-
# generate header merged scripts
|
790 |
-
if(count($scripts_header) > 0) {
|
791 |
-
|
792 |
-
# merge code, generate cache file paths and urls
|
793 |
-
$fheader_code = implode('', $scripts_header);
|
794 |
-
$js_header_uid = $tvers.'-'.hash('sha1', $fheader_code).'.header';
|
795 |
-
$fheader = $fvm_cache_paths['cache_dir_min'] . DIRECTORY_SEPARATOR . $js_header_uid.'.min.js';
|
796 |
-
$fheader_url = $fvm_cache_paths['cache_url_min'].'/'.$js_header_uid.'.min.js';
|
797 |
|
798 |
-
#
|
799 |
-
if(isset($
|
800 |
-
|
801 |
-
|
802 |
-
|
|
|
|
|
|
|
803 |
}
|
804 |
-
}
|
805 |
-
|
806 |
-
# generate cache file
|
807 |
-
clearstatcache();
|
808 |
-
if (!file_exists($fheader)) {
|
809 |
|
810 |
-
#
|
811 |
-
$
|
812 |
-
$log_meta = array('loc'=>home_url(add_query_arg(NULL, NULL)), 'fl'=>$fheader_url);
|
813 |
|
814 |
-
#
|
815 |
-
if(!
|
816 |
-
|
817 |
-
fvm_save_file($fheader, $fheader_code);
|
818 |
-
}
|
819 |
-
}
|
820 |
-
|
821 |
-
# preload and save for html implementation (with priority order prefix)
|
822 |
-
if(!isset($fvm_settings['js']['nopreload']) || (isset($fvm_settings['js']['nopreload']) && $fvm_settings['js']['nopreload'] != true)) {
|
823 |
-
$allpreloads['high'][] = '<link rel="preload" href="'.$fheader_url.'" as="script" importance="high" />';
|
824 |
-
}
|
825 |
-
|
826 |
-
# header
|
827 |
-
$htmljscodeheader['c_'.$js_header_uid] = '<script data-cfasync="false" src="'.$fheader_url.'"></script>';
|
828 |
-
|
829 |
-
}
|
830 |
-
|
831 |
-
# generate footer merged scripts
|
832 |
-
if(count($scripts_footer) > 0) {
|
833 |
-
|
834 |
-
# merge code, generate cache file paths and urls
|
835 |
-
$ffooter_code = implode('', $scripts_footer);
|
836 |
-
$js_ffooter_uid = $tvers.'-'.hash('sha1', $ffooter_code).'.footer';
|
837 |
-
$ffooter = $fvm_cache_paths['cache_dir_min'] . DIRECTORY_SEPARATOR . $js_ffooter_uid.'.min.js';
|
838 |
-
$ffooter_url = $fvm_cache_paths['cache_url_min'].'/'.$js_ffooter_uid.'.min.js';
|
839 |
-
|
840 |
-
# add cdn support
|
841 |
-
if(isset($fvm_settings['cdn']['enable']) && $fvm_settings['cdn']['enable'] == true &&
|
842 |
-
isset($fvm_settings['cdn']['domain']) && !empty($fvm_settings['cdn']['domain'])) {
|
843 |
-
if(isset($fvm_settings['cdn']['jsok']) && $fvm_settings['cdn']['jsok'] == true) {
|
844 |
-
$ffooter_url = str_replace('//'.$fvm_urls['wp_domain'], '//'.$fvm_settings['cdn']['domain'], $ffooter_url);
|
845 |
-
|
846 |
}
|
847 |
-
}
|
848 |
-
|
849 |
-
# generate cache file
|
850 |
-
clearstatcache();
|
851 |
-
if (!file_exists($ffooter)) {
|
852 |
|
853 |
-
#
|
854 |
-
$
|
855 |
-
|
856 |
-
|
857 |
-
|
858 |
-
|
859 |
-
|
860 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
861 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
862 |
}
|
863 |
-
|
864 |
-
|
865 |
-
if(!isset($fvm_settings['js']['nopreload']) || (isset($fvm_settings['js']['nopreload']) && $fvm_settings['js']['nopreload'] != true)) {
|
866 |
-
$allpreloads['low'][] = '<link rel="preload" href="'.$ffooter_url.'" as="script" importance="low" />';
|
867 |
-
}
|
868 |
-
|
869 |
-
# header
|
870 |
-
$htmljscodedefer['d_'.$js_ffooter_uid] = '<script data-cfasync="false" defer src="'.$ffooter_url.'"></script>';
|
871 |
-
|
872 |
}
|
873 |
-
|
874 |
}
|
875 |
-
|
876 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
877 |
|
878 |
-
#
|
879 |
-
|
|
|
|
|
880 |
|
881 |
-
#
|
882 |
-
|
883 |
-
|
884 |
-
|
885 |
-
|
|
|
|
|
|
|
|
|
|
|
886 |
}
|
887 |
|
888 |
-
#
|
889 |
-
if(isset($fvm_settings['
|
890 |
-
|
891 |
-
|
892 |
-
}
|
893 |
}
|
894 |
|
|
|
|
|
|
|
895 |
}
|
896 |
|
897 |
-
#
|
898 |
-
$
|
899 |
-
|
900 |
-
# build extra head and footer ###############################
|
901 |
-
|
902 |
-
# header and footer markers
|
903 |
-
$hm = '<!-- h_preheader --><!-- h_header_function --><!-- h_cssheader --><!-- h_jsheader -->';
|
904 |
-
$fm = '<!-- h_footer_lozad -->';
|
905 |
-
|
906 |
-
# add our function to head
|
907 |
-
$hm = fvm_add_header_function($hm);
|
908 |
-
|
909 |
-
# remove charset meta tag and collect it to first position
|
910 |
-
if(!is_null($html->find('meta[charset]', 0))) {
|
911 |
-
$hm = str_replace('<!-- h_preheader -->', $html->find('meta[charset]', 0)->outertext.'<!-- h_preheader -->', $hm);
|
912 |
-
foreach($html->find('meta[charset]') as $element) { $element->outertext = ''; }
|
913 |
-
}
|
914 |
-
|
915 |
-
# preload headers, by importance
|
916 |
-
if(is_array($allpreloads)) {
|
917 |
-
|
918 |
-
# start
|
919 |
-
$preload = '';
|
920 |
|
921 |
-
#
|
922 |
-
|
923 |
-
|
924 |
-
|
925 |
-
|
926 |
-
|
927 |
-
if(isset($allpreloads['high'])) {
|
928 |
-
$preload.= implode(PHP_EOL, $allpreloads['high']);
|
929 |
-
}
|
930 |
-
|
931 |
-
# auto priority
|
932 |
-
if(isset($allpreloads['auto'])) {
|
933 |
-
$preload.= implode(PHP_EOL, $allpreloads['auto']);
|
934 |
-
}
|
935 |
|
936 |
-
#
|
937 |
-
if(isset($
|
938 |
-
$
|
939 |
-
}
|
940 |
-
|
941 |
-
# add preload
|
942 |
-
if(!empty($preload)) {
|
943 |
-
$hm = str_replace('<!-- h_preheader -->', $preload.'<!-- h_preheader -->', $hm);
|
944 |
}
|
945 |
-
|
|
|
|
|
946 |
|
947 |
-
# add critical path
|
948 |
-
if(isset($critical_path)) {
|
949 |
-
if(is_array($critical_path) && count($critical_path) > 0) {
|
950 |
-
$hm = str_replace('<!-- h_preheader -->', implode(PHP_EOL, $critical_path).'<!-- h_preheader -->', $hm);
|
951 |
-
}
|
952 |
}
|
953 |
|
954 |
-
|
955 |
-
|
956 |
-
|
957 |
-
|
958 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
959 |
}
|
960 |
}
|
961 |
|
962 |
-
#
|
963 |
-
if(isset($
|
964 |
-
|
965 |
-
|
966 |
-
|
|
|
967 |
}
|
968 |
-
|
969 |
-
|
970 |
-
|
971 |
-
|
972 |
-
if(
|
973 |
-
|
974 |
-
|
|
|
975 |
}
|
976 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
977 |
|
978 |
-
|
979 |
-
|
980 |
-
|
981 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
982 |
|
983 |
-
|
984 |
-
|
|
|
985 |
|
986 |
-
#
|
987 |
-
|
988 |
-
|
989 |
-
|
990 |
-
|
|
|
|
|
|
|
991 |
}
|
992 |
}
|
993 |
|
994 |
-
#
|
995 |
-
$
|
996 |
-
|
997 |
-
# minify HTML, if not disabled
|
998 |
-
if(!isset($fvm_settings['html']['min_disable']) || (isset($fvm_settings['html']['min_disable']) && $fvm_settings['html']['min_disable'] != true)) {
|
999 |
-
$html = fvm_raisermin_html($html, true);
|
1000 |
}
|
1001 |
|
1002 |
}
|
1003 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1004 |
# return html
|
1005 |
return $html;
|
1006 |
|
34 |
|
35 |
# start buffering before template
|
36 |
function fvm_start_buffer() {
|
37 |
+
if(fvm_can_minify_css() || fvm_can_minify_js() || fvm_can_process_html()) {
|
38 |
ob_start('fvm_process_page', 0, PHP_OUTPUT_HANDLER_REMOVABLE);
|
39 |
}
|
40 |
}
|
45 |
# get globals
|
46 |
global $fvm_settings, $fvm_cache_paths, $fvm_urls;
|
47 |
|
48 |
+
# get html into an object
|
49 |
+
# https://simplehtmldom.sourceforge.io/manual.htm
|
50 |
+
$html_object = 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)) {
|
54 |
+
return $html . '<!-- simplehtmldom failed to process the html -->';
|
55 |
+
} else {
|
56 |
+
$html = $html_object;
|
57 |
+
}
|
58 |
+
|
59 |
+
# get globals
|
60 |
+
global $fvm_settings, $fvm_urls;
|
61 |
+
|
62 |
+
# defaults
|
63 |
+
$tvers = get_option('fvm_last_cache_update', '0');
|
64 |
+
$httppreloads = array();
|
65 |
+
$htmlpreloads = array();
|
66 |
+
$htmlcssheader = array();
|
67 |
+
$htmljsheader = array();
|
68 |
+
$htmljsdefer = array();
|
69 |
+
|
70 |
+
|
71 |
+
# collect all link preload headers, skip amp
|
72 |
+
if(fvm_is_amp_page() !== true) {
|
73 |
+
# add other preloads
|
74 |
+
foreach($html->find('link[rel=preload]') as $tag) {
|
75 |
+
$htmlpreloads[] = $tag->outertext;
|
76 |
+
$tag->outertext = '';
|
77 |
}
|
78 |
+
}
|
79 |
+
|
80 |
+
|
81 |
+
# START CSS PROCESSING
|
82 |
+
if(fvm_can_minify_css()) {
|
83 |
+
|
84 |
# defaults
|
85 |
+
$fvm_styles = array();
|
86 |
+
$allcss = array();
|
87 |
+
$css_lowpriority_code = '';
|
88 |
+
|
89 |
+
# start log
|
90 |
+
$log = array();
|
91 |
+
$css_total = 0;
|
92 |
+
|
93 |
+
# start log
|
94 |
+
$log[]= 'PAGE - '. fvm_get_uripath(true) . PHP_EOL . '---' . PHP_EOL;
|
95 |
+
|
96 |
+
|
97 |
+
# exclude styles and link tags inside scripts, no scripts or html comments
|
98 |
+
$excl = array();
|
99 |
+
foreach($html->find('script link[rel=stylesheet], script style, noscript style, noscript link[rel=stylesheet], comment') as $element) {
|
100 |
+
$excl[] = $element->outertext;
|
101 |
+
}
|
102 |
|
103 |
+
# collect all styles, but filter out if excluded
|
104 |
+
foreach($html->find('link[rel=stylesheet], style') as $element) {
|
105 |
+
if(!in_array($element->outertext, $excl)) {
|
106 |
+
$allcss[] = $element;
|
107 |
+
}
|
108 |
}
|
109 |
|
110 |
+
# START CSS LOOP
|
111 |
+
foreach($allcss as $k=>$tag) {
|
|
|
|
|
112 |
|
113 |
+
# mediatypes
|
114 |
+
if(isset($tag->media)) {
|
|
|
|
|
|
|
|
|
|
|
115 |
|
116 |
+
# Normalize mediatypes
|
117 |
+
if($tag->media == 'screen' || $tag->media == 'screen, print' || strlen($tag->media) == 0) {
|
118 |
+
$tag->media = 'all';
|
119 |
+
}
|
120 |
+
|
121 |
+
# Remove print styles
|
122 |
+
if(isset($fvm_settings['css']['noprint']) && $fvm_settings['css']['noprint'] == true && $tag->media == 'print'){
|
123 |
+
$tag->outertext = '';
|
124 |
+
unset($allcss[$k]);
|
125 |
+
continue;
|
126 |
+
}
|
127 |
+
|
128 |
+
} else {
|
129 |
+
# must have
|
130 |
+
$tag->media = 'all';
|
131 |
}
|
132 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
133 |
|
134 |
+
# START CSS FILES
|
135 |
+
if($tag->tag == 'link' && isset($tag->href)) {
|
|
|
|
|
|
|
136 |
|
137 |
+
# Ignore css files
|
138 |
+
$ignore_css_merging = false;
|
139 |
+
if(isset($fvm_settings['css']['ignore']) && !empty($fvm_settings['css']['ignore'])) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
140 |
$arr = fvm_string_toarray($fvm_settings['css']['ignore']);
|
141 |
if(is_array($arr) && count($arr) > 0) {
|
142 |
foreach ($arr as $e) {
|
143 |
if(stripos($tag->href, $e) !== false) {
|
144 |
+
unset($allcss[$k]);
|
145 |
continue 2;
|
146 |
}
|
147 |
}
|
148 |
}
|
149 |
+
}
|
150 |
+
|
151 |
+
# Remove CSS files
|
152 |
+
if(isset($fvm_settings['css']['remove']) && !empty($fvm_settings['css']['remove'])) {
|
153 |
$arr = fvm_string_toarray($fvm_settings['css']['remove']);
|
154 |
if(is_array($arr) && count($arr) > 0) {
|
155 |
foreach ($arr as $e) {
|
162 |
}
|
163 |
}
|
164 |
|
165 |
+
# css merging functionality
|
166 |
+
if(isset($fvm_settings['css']['combine']) && $fvm_settings['css']['combine'] == true) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
167 |
|
168 |
+
# download or fetch from transient, minified
|
169 |
+
$css = fvm_get_css_from_file($tag);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
170 |
|
171 |
+
if($css !== false && is_array($css)) {
|
|
|
|
|
|
|
172 |
|
173 |
+
# extract fonts and icons
|
174 |
+
if(isset($fvm_settings['css']['fonts']) && $fvm_settings['css']['fonts'] == true) {
|
175 |
+
$extract_fonts_arr = fvm_extract_fonts($css['code']);
|
176 |
+
$css_lowpriority_code.= '/* '.$tag->href.' */'. PHP_EOL . $extract_fonts_arr['fonts'];
|
177 |
+
$css_code = $extract_fonts_arr['code'];
|
178 |
+
} else {
|
179 |
+
$css_code = $css['code'];
|
180 |
+
}
|
|
|
181 |
|
182 |
+
|
183 |
+
# async from the list only
|
184 |
+
if(isset($fvm_settings['css']['async']) && $fvm_settings['css']['async'] == true) {
|
185 |
+
if(isset($fvm_settings['css']['async']) && !empty($fvm_settings['css']['async'])) {
|
186 |
+
$arr = fvm_string_toarray($fvm_settings['css']['async']);
|
187 |
+
if(is_array($arr) && count($arr) > 0) {
|
188 |
+
foreach ($arr as $aa) {
|
189 |
+
if(stripos($tag->href, $aa) !== false) {
|
190 |
|
191 |
+
# save css for merging
|
192 |
+
$fvm_styles[$tag->media]['async'][] = $css_code;
|
193 |
+
|
194 |
+
# log
|
195 |
+
$size = strlen($css['code']);
|
196 |
+
$css_total = $css_total + $size;
|
197 |
+
$log[] = '[CSS Async: '.str_pad(fvm_format_filesize($size), 9,' ',STR_PAD_LEFT).']'."\t".str_replace($fvm_urls['wp_site_url'], '', $css['url']). PHP_EOL;
|
|
|
|
|
|
|
|
|
|
|
|
|
198 |
|
199 |
+
# finish early
|
200 |
+
$tag->outertext = '';
|
201 |
+
unset($allcss[$k]);
|
202 |
+
continue 2;
|
203 |
+
|
204 |
+
}
|
205 |
+
}
|
206 |
+
}
|
207 |
}
|
208 |
}
|
209 |
+
|
210 |
+
# else render block
|
211 |
+
|
212 |
+
# save css for merging as fallback
|
213 |
+
$fvm_styles[$tag->media]['block'][] = $css_code;
|
214 |
+
|
215 |
+
# log
|
216 |
+
$size = strlen($css['code']);
|
217 |
+
$css_total = $css_total + $size;
|
218 |
+
$log[] = '[CSS Block: '.str_pad(fvm_format_filesize($size), 9,' ',STR_PAD_LEFT).']'."\t".str_replace($fvm_urls['wp_site_url'], '', $css['url']). PHP_EOL;
|
219 |
+
|
220 |
+
# finish early
|
221 |
+
$tag->outertext = '';
|
222 |
+
unset($allcss[$k]);
|
223 |
+
continue;
|
224 |
+
|
225 |
}
|
226 |
+
}
|
227 |
+
|
228 |
+
|
229 |
+
# minify individually, if enabled
|
230 |
+
if(!isset($fvm_settings['css']['min_disable']) || (isset($fvm_settings['css']['min_disable'])&& $fvm_settings['css']['min_disable'] != true)) {
|
231 |
|
232 |
+
# download or fetch from transient, minified
|
233 |
+
$css = fvm_get_css_from_file($tag);
|
234 |
|
235 |
+
if($css !== false && is_array($css)) {
|
|
|
236 |
|
237 |
+
# extract fonts and icons
|
238 |
+
if(isset($fvm_settings['css']['fonts']) && $fvm_settings['css']['fonts'] == true) {
|
239 |
+
$extract_fonts_arr = fvm_extract_fonts($css['code']);
|
240 |
+
$css_lowpriority_code.= '/* '.$tag->href.' */'. PHP_EOL . $extract_fonts_arr['fonts'];
|
241 |
+
$css_code = $extract_fonts_arr['code'];
|
|
|
242 |
} else {
|
243 |
+
$css_code = $css['code'];
|
244 |
+
}
|
245 |
+
|
246 |
+
# empty files
|
247 |
+
if(empty(trim($css_code))) {
|
248 |
$tag->outertext = '';
|
249 |
unset($allcss[$k]);
|
250 |
continue;
|
251 |
+
} else {
|
252 |
+
$css_code = '/* '.$tag->href.' */'. PHP_EOL . $css_code;
|
253 |
}
|
254 |
+
|
255 |
+
# generate url
|
256 |
+
$ind_css_url = fvm_generate_min_url($tag->href, $css['tkey'], 'css', $css_code);
|
257 |
+
|
258 |
+
# cdn
|
259 |
+
if(isset($fvm_settings['cdn']['cssok']) && $fvm_settings['cdn']['cssok'] == true) {
|
260 |
+
$ind_css_url = fvm_rewrite_cdn_url($ind_css_url);
|
261 |
+
}
|
262 |
+
|
263 |
+
# async from the list only
|
264 |
+
if(isset($fvm_settings['css']['async']) && !empty($fvm_settings['css']['async'])) {
|
265 |
+
$arr = fvm_string_toarray($fvm_settings['css']['async']);
|
266 |
+
if(is_array($arr) && count($arr) > 0) {
|
267 |
+
foreach ($arr as $aa) {
|
268 |
+
if(stripos($tag->href, $aa) !== false) {
|
269 |
|
270 |
+
# async attributes
|
271 |
+
$tag->rel = 'preload';
|
272 |
+
$tag->as = 'style';
|
273 |
+
$tag->onload = "this.rel='stylesheet';this.onload=null";
|
|
|
274 |
|
275 |
+
# log
|
276 |
+
$size = strlen($css['code']);
|
277 |
+
$css_total = $css_total + $size;
|
278 |
+
$log[] = '[CSS Async: '.str_pad(fvm_format_filesize($size), 9,' ',STR_PAD_LEFT).']'."\t".str_replace($fvm_urls['wp_site_url'], '', $css['url']). PHP_EOL;
|
279 |
+
|
280 |
+
# finish early
|
281 |
+
$tag->href = $ind_css_url;
|
282 |
+
unset($allcss[$k]);
|
283 |
+
continue 2;
|
284 |
+
|
285 |
+
}
|
286 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
287 |
}
|
288 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
289 |
|
290 |
+
# force render blocking for other files
|
291 |
+
|
292 |
+
# http and html preload for render blocking css
|
293 |
+
if(!isset($fvm_settings['css']['nopreload']) || (isset($fvm_settings['css']['nopreload']) && $fvm_settings['css']['nopreload'] != true)) {
|
294 |
+
$httppreloads[] = '<'.$ind_css_url.'>; rel=preload; as=style';
|
295 |
+
$htmlpreloads[] = '<link rel="preload" href="'.$ind_css_url.'" as="style" media="'.$tag->media.'" />';
|
296 |
}
|
297 |
+
|
298 |
+
# log
|
299 |
+
$size = strlen($css['code']);
|
300 |
+
$css_total = $css_total + $size;
|
301 |
+
$log[] = '[CSS Block: '.str_pad(fvm_format_filesize($size), 9,' ',STR_PAD_LEFT).']'."\t".str_replace($fvm_urls['wp_site_url'], '', $css['url']). PHP_EOL;
|
302 |
+
|
303 |
+
# finish early
|
304 |
+
$tag->href = $ind_css_url;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
305 |
unset($allcss[$k]);
|
306 |
+
|
307 |
}
|
|
|
308 |
}
|
|
|
309 |
}
|
310 |
+
# END CSS FILES
|
311 |
+
|
312 |
|
313 |
+
# START STYLE TAGS
|
314 |
+
if($tag->tag == 'style' && !isset($tag->href)) {
|
315 |
+
|
316 |
+
# remove if empty
|
317 |
+
if(strlen(trim($tag->innertext)) == 0) {
|
318 |
+
$tag->outertext = '';
|
319 |
+
unset($allcss[$k]);
|
320 |
+
continue;
|
321 |
+
}
|
322 |
|
323 |
+
# default
|
324 |
+
$css = $tag->innertext;
|
|
|
325 |
|
326 |
+
# minify?
|
327 |
+
if(!isset($fvm_settings['css']['min_disable_styles']) || (isset($fvm_settings['css']['min_disable_styles'])&& $fvm_settings['css']['min_disable_styles'] != true)) {
|
328 |
+
$css = fvm_minify_css_string($css);
|
329 |
+
}
|
|
|
|
|
|
|
|
|
330 |
|
331 |
+
# handle import rules
|
332 |
+
$css = fvm_replace_css_imports($css);
|
333 |
+
|
334 |
+
# simplify font face
|
335 |
+
$arr = fvm_simplify_fontface($css);
|
336 |
+
if($arr !== false && is_array($arr)) {
|
337 |
+
$css = str_replace($arr['before'], $arr['after'], $css);
|
338 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
339 |
|
340 |
+
# extract fonts and icons
|
341 |
+
if(isset($fvm_settings['css']['fonts']) && $fvm_settings['css']['fonts'] == true) {
|
342 |
+
$extract_fonts_arr = fvm_extract_fonts($css);
|
343 |
+
$css_lowpriority_code.= $extract_fonts_arr['fonts'];
|
344 |
+
$css = $extract_fonts_arr['code'];
|
345 |
+
}
|
346 |
+
|
347 |
+
# add filtered css code
|
348 |
+
if(!empty($css)) {
|
349 |
+
$tag->innertext = $css;
|
350 |
+
unset($allcss[$k]);
|
351 |
+
continue;
|
352 |
}
|
353 |
|
354 |
+
}
|
355 |
+
# END STYLE TAGS
|
356 |
+
|
357 |
+
}
|
358 |
+
# END CSS LOOP
|
359 |
+
|
360 |
+
# START CSS LOG
|
361 |
+
if(count($log) > 1) {
|
362 |
+
$log[] = str_pad('-', 22, '-',STR_PAD_LEFT) . PHP_EOL;
|
363 |
+
$log[] = '[CSS Total: '.str_pad(fvm_format_filesize($css_total), 9,' ',STR_PAD_LEFT).']' . PHP_EOL;
|
364 |
+
$log[] = str_pad('-', 22, '-',STR_PAD_LEFT);
|
365 |
+
fvm_save_log(array('type'=>'min','msg'=>implode('', $log)));
|
366 |
+
}
|
367 |
+
# END CSS LOG
|
368 |
+
|
369 |
+
|
370 |
+
# START OPTIMIZED FONT DELIVERY
|
371 |
+
if(!empty($css_lowpriority_code)) {
|
372 |
+
|
373 |
+
# minify?
|
374 |
+
if(!isset($fvm_settings['css']['min_disable']) || (isset($fvm_settings['css']['min_disable'])&& $fvm_settings['css']['min_disable'] != true)) {
|
375 |
+
$css_lowpriority_code = fvm_minify_css_string($css_lowpriority_code);
|
376 |
+
}
|
377 |
+
|
378 |
+
# save transient, if not yet saved
|
379 |
+
$tkey = fvm_generate_hash_with_prefix(hash('sha256', $css_lowpriority_code), 'css');
|
380 |
+
|
381 |
+
# generate url
|
382 |
+
$css_fonts_url = fvm_generate_min_url('fonts', $tkey, 'css', $css_lowpriority_code);
|
383 |
+
|
384 |
+
# cdn
|
385 |
+
if(isset($fvm_settings['cdn']['cssok']) && $fvm_settings['cdn']['cssok'] == true) {
|
386 |
+
$css_fonts_url = fvm_rewrite_cdn_url($css_fonts_url);
|
387 |
+
}
|
388 |
+
|
389 |
+
# preload
|
390 |
+
$htmlcssheader[0] = '<link id="fvm-fonts" rel="stylesheet" href="'.$css_fonts_url.'" media="fonts" onload="if(fvmuag()){this.media=\'all\'}" />';
|
391 |
+
|
392 |
+
}
|
393 |
+
# END OPTIMIZED FONT DELIVERY
|
394 |
+
|
395 |
+
# START COMBINING CSS
|
396 |
+
if(is_array($fvm_styles) && count($fvm_styles) > 0) {
|
397 |
+
|
398 |
+
# process mediatypes
|
399 |
+
foreach ($fvm_styles as $mediatype=>$css_arr) {
|
400 |
|
401 |
+
# process types, block or async
|
402 |
+
foreach ($css_arr as $css_method=>$css_arr2) {
|
403 |
+
|
404 |
+
# merge and hash
|
405 |
+
$merged_css = implode(PHP_EOL, $css_arr2);
|
406 |
+
$tkey = fvm_generate_hash_with_prefix(hash('sha256', $merged_css), 'css');
|
407 |
|
408 |
+
# inline if small
|
409 |
+
if(strlen($merged_css) < 15000 && $css_method == 'block') {
|
410 |
+
$htmlcssheader[] = '<style type="text/css" media="'.$mediatype.'">'.$merged_css.'</style>';
|
411 |
+
continue;
|
412 |
+
}
|
413 |
|
414 |
+
# url, preload, add
|
415 |
+
$merged_css_url = fvm_generate_min_url('combined', $tkey, 'css', $merged_css);
|
|
|
|
|
|
|
416 |
|
417 |
+
# cdn
|
418 |
+
if(isset($fvm_settings['cdn']['cssok']) && $fvm_settings['cdn']['cssok'] == true) {
|
419 |
+
$merged_css_url = fvm_rewrite_cdn_url($merged_css_url);
|
|
|
|
|
|
|
420 |
}
|
421 |
+
|
422 |
+
# http, html preload + header
|
423 |
+
if($css_method == 'block') {
|
424 |
|
425 |
+
# add to header
|
426 |
+
$htmlcssheader[] = '<link rel="stylesheet" href="'.$merged_css_url.'" media="'.$mediatype.'" />';
|
|
|
427 |
|
428 |
+
# http and html preload for render blocking css
|
429 |
+
if(!isset($fvm_settings['css']['nopreload']) || (isset($fvm_settings['css']['nopreload']) && $fvm_settings['css']['nopreload'] != true)) {
|
430 |
+
$httppreloads[] = '<'.$merged_css_url.'>; rel=preload; as=style';
|
431 |
+
$htmlpreloads[] = '<link rel="preload" href="'.$merged_css_url.'" as="style" media="'.$mediatype.'" />';
|
432 |
+
}
|
433 |
|
434 |
+
} else {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
435 |
|
436 |
+
# async
|
437 |
+
$htmlcssheader[] = '<link rel="preload" as="style" href="'.$merged_css_url.'" media="'.$mediatype.'" onload="this.rel=\'stylesheet\'" />';
|
438 |
|
439 |
+
}
|
440 |
+
|
441 |
+
}
|
|
|
442 |
}
|
443 |
}
|
444 |
+
# END COMBINING CSS
|
445 |
+
|
446 |
+
}
|
447 |
+
# END CSS PROCESSING
|
448 |
+
|
449 |
+
|
450 |
+
# START JS PROCESSING
|
451 |
+
if(fvm_can_minify_js()) {
|
452 |
+
|
453 |
+
# defaults
|
454 |
+
$scripts_duplicate_check = array();
|
455 |
+
$fvm_scripts_header = array();
|
456 |
+
$fvm_scripts_defer = array();
|
457 |
|
458 |
+
# start log
|
459 |
+
$log = array();
|
460 |
+
$js_total = 0;
|
461 |
|
462 |
+
# start log
|
463 |
+
$log[]= 'PAGE - '. fvm_get_uripath(true) . PHP_EOL . '---' . PHP_EOL;
|
464 |
+
|
465 |
+
# get all scripts
|
466 |
+
$allscripts = array();
|
467 |
+
foreach($html->find('script') as $element) {
|
468 |
+
$allscripts[] = $element;
|
469 |
+
}
|
|
|
|
|
470 |
|
471 |
+
# START JS LOOP
|
472 |
+
if (is_array($allscripts) && count($allscripts) > 0) {
|
473 |
+
foreach($allscripts as $k=>$tag) {
|
474 |
+
|
475 |
+
# handle application/ld+json or application/json before anything else
|
476 |
+
if(isset($tag->type) && ($tag->type == 'application/ld+json' || $tag->type == 'application/json')) {
|
477 |
+
|
478 |
+
# minify
|
479 |
+
if(isset($fvm_settings['js']['js_enable_min_inline']) && $fvm_settings['js']['js_enable_min_inline'] == true) { $tag->innertext = fvm_minify_microdata($tag->innertext); }
|
480 |
+
|
481 |
+
# remove
|
482 |
+
unset($allscripts[$k]);
|
483 |
+
continue;
|
484 |
+
}
|
485 |
+
|
486 |
+
# skip unknown script types
|
487 |
+
if(isset($tag->type) && $tag->type != 'text/javascript') {
|
488 |
+
unset($allscripts[$k]);
|
489 |
+
continue;
|
490 |
+
}
|
491 |
+
|
492 |
+
# remove default script type
|
493 |
+
if(isset($tag->type) && $tag->type == 'text/javascript') { unset($tag->type); }
|
494 |
+
|
495 |
+
# START JS FILES
|
496 |
+
if(isset($tag->src)) {
|
497 |
+
|
498 |
+
# ignore js files
|
499 |
+
if(isset($fvm_settings['js']['ignore']) && !empty($fvm_settings['js']['ignore'])) {
|
500 |
+
$arr = fvm_string_toarray($fvm_settings['js']['ignore']);
|
501 |
+
if(is_array($arr) && count($arr) > 0) {
|
502 |
+
foreach ($arr as $a) {
|
503 |
+
if(stripos($tag->src, $a) !== false) {
|
504 |
+
unset($allscripts[$k]);
|
505 |
+
continue 2;
|
506 |
+
}
|
507 |
+
}
|
508 |
+
}
|
509 |
}
|
510 |
|
511 |
+
# remove js files
|
512 |
+
if(isset($fvm_settings['js']['remove']) && !empty($fvm_settings['js']['remove'])) {
|
513 |
$arr = fvm_string_toarray($fvm_settings['js']['remove']);
|
514 |
if(is_array($arr) && count($arr) > 0) {
|
515 |
+
foreach ($arr as $a) {
|
516 |
+
if(stripos($tag->src, $a) !== false) {
|
517 |
$tag->outertext = '';
|
518 |
unset($allscripts[$k]);
|
519 |
continue 2;
|
522 |
}
|
523 |
}
|
524 |
|
525 |
+
|
526 |
+
# JS files to delay until user interaction (unmergeable)
|
527 |
+
if(isset($fvm_settings['js']['thirdparty']) && !empty($fvm_settings['js']['thirdparty'])) {
|
528 |
+
$arr = fvm_string_toarray($fvm_settings['js']['thirdparty']);
|
529 |
+
if(is_array($arr) && count($arr) > 0) {
|
530 |
+
foreach ($arr as $ac) {
|
531 |
+
if(stripos($tag->src, $ac) !== false) {
|
532 |
+
|
533 |
+
# unique identifier
|
534 |
+
$uid = fvm_generate_hash_with_prefix(hash('sha256', $tag->outertext), 'js');
|
535 |
+
|
536 |
+
# remove exact duplicates, or replace transformed tag
|
537 |
+
if(isset($scripts_duplicate_check[$uid])) {
|
538 |
+
$tag->outertext = '';
|
539 |
+
} else {
|
540 |
+
$tag->type = 'fvm-script-delay';
|
541 |
+
$scripts_duplicate_check[$uid] = $uid;
|
542 |
+
}
|
543 |
+
|
544 |
+
# mark as processed, unset and break inner loop
|
545 |
+
unset($allscripts[$k]);
|
546 |
+
continue 2;
|
547 |
+
|
548 |
+
}
|
549 |
+
}
|
550 |
+
}
|
551 |
+
}
|
552 |
+
|
553 |
+
|
554 |
+
# START MERGING JS
|
555 |
+
if(isset($fvm_settings['js']['combine']) && $fvm_settings['js']['combine'] == true) {
|
556 |
+
|
557 |
+
# force render blocking
|
558 |
+
if(isset($fvm_settings['js']['merge_header']) && !empty($fvm_settings['js']['merge_header'])) {
|
559 |
+
$arr = fvm_string_toarray($fvm_settings['js']['merge_header']);
|
560 |
+
if(is_array($arr) && count($arr) > 0) {
|
561 |
+
foreach ($arr as $aa) {
|
562 |
+
if(stripos($tag->src, $aa) !== false) {
|
563 |
+
|
564 |
+
# download or fetch from transient, minified
|
565 |
+
$js = fvm_get_js_from_file($tag);
|
566 |
+
if($js !== false && is_array($js)) {
|
567 |
+
|
568 |
+
# save js for merging
|
569 |
+
$fvm_scripts_header[] = $js['code'];
|
570 |
+
|
571 |
+
# log
|
572 |
+
$size = strlen($js['code']);
|
573 |
+
$js_total = $js_total + $size;
|
574 |
+
$log[] = '[JS Block: '.str_pad(fvm_format_filesize($size), 9,' ',STR_PAD_LEFT).']'."\t".str_replace($fvm_urls['wp_site_url'], '', $js['url']). PHP_EOL;
|
575 |
+
|
576 |
+
# remove from html
|
577 |
+
$tag->outertext = '';
|
578 |
+
unset($allscripts[$k]);
|
579 |
+
continue 2;
|
580 |
+
|
581 |
}
|
582 |
+
}
|
583 |
}
|
584 |
}
|
585 |
}
|
586 |
|
587 |
+
# force defer
|
588 |
+
if(isset($fvm_settings['js']['merge_defer']) && !empty($fvm_settings['js']['merge_defer'])) {
|
589 |
+
$arr = fvm_string_toarray($fvm_settings['js']['merge_defer']);
|
590 |
if(is_array($arr) && count($arr) > 0) {
|
591 |
+
foreach ($arr as $aa) {
|
592 |
+
if(stripos($tag->src, $aa) !== false) {
|
593 |
+
|
594 |
+
# download or fetch from transient, minified
|
595 |
+
$js = fvm_get_js_from_file($tag);
|
596 |
+
if($js !== false && is_array($js)) {
|
597 |
+
|
598 |
+
# save js for merging
|
599 |
+
$fvm_scripts_defer[] = $js['code'];
|
600 |
+
|
601 |
+
# log
|
602 |
+
$size = strlen($js['code']);
|
603 |
+
$js_total = $js_total + $size;
|
604 |
+
$log[] = '[JS Defer: '.str_pad(fvm_format_filesize($size), 9,' ',STR_PAD_LEFT).']'."\t".str_replace($fvm_urls['wp_site_url'], '', $js['url']). PHP_EOL;
|
605 |
+
|
606 |
+
# remove from html
|
607 |
+
$tag->outertext = '';
|
608 |
+
unset($allscripts[$k]);
|
609 |
+
continue 2;
|
610 |
+
|
611 |
+
}
|
612 |
}
|
613 |
}
|
614 |
}
|
615 |
}
|
|
|
616 |
|
617 |
+
# jquery needs to load earlier, if not being merged (while merging is active)
|
618 |
+
if(stripos($tag->src, '/jquery.js') !== false || stripos($tag->src, '/jquery.min.js') !== false || stripos($tag->src, '/jquery-migrate') !== false) {
|
619 |
|
620 |
+
# filter url
|
621 |
+
$href = fvm_normalize_url($tag->src);
|
622 |
+
|
623 |
+
# http and html preload for render blocking js
|
624 |
+
if(!isset($fvm_settings['js']['nopreload']) || (isset($fvm_settings['js']['nopreload']) && $fvm_settings['js']['nopreload'] != true)) {
|
625 |
+
$httppreloads[] = '<'.$href.'>; rel=preload; as=script';
|
626 |
+
$htmlpreloads[] = '<link rel="preload" href="'.$href.'" as="script" />';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
627 |
}
|
628 |
+
|
629 |
+
# header
|
630 |
+
if(stripos($tag->src, '/jquery-migrate') !== false) {
|
631 |
+
$htmljsheader[1] = "<script data-cfasync='false' src='".$href."'></script>"; # jquery migrate
|
632 |
+
} else {
|
633 |
+
$htmljsheader[0] = "<script data-cfasync='false' src='".$tag->src."'></script>"; # jquery
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
634 |
}
|
635 |
+
|
636 |
+
# content
|
637 |
+
$tag->outertext = '';
|
638 |
+
unset($allscripts[$k]);
|
639 |
+
continue;
|
640 |
+
}
|
641 |
|
642 |
+
}
|
643 |
+
# END MERGING JS
|
644 |
+
|
645 |
+
|
646 |
+
# START INDIVIDUAL JS MINIFICATION
|
647 |
+
# minify individually, if enabled
|
648 |
+
if(!isset($fvm_settings['js']['min_disable']) || (isset($fvm_settings['js']['min_disable'])&& $fvm_settings['js']['min_disable'] != true)) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
649 |
|
650 |
+
# force render blocking
|
651 |
if(isset($fvm_settings['js']['merge_header']) && !empty($fvm_settings['js']['merge_header'])) {
|
652 |
$arr = fvm_string_toarray($fvm_settings['js']['merge_header']);
|
653 |
if(is_array($arr) && count($arr) > 0) {
|
654 |
+
foreach ($arr as $aa) {
|
655 |
+
if(stripos($tag->src, $aa) !== false) {
|
656 |
|
657 |
+
# download or fetch from transient, minified
|
658 |
+
$js = fvm_get_js_from_file($tag);
|
659 |
+
if($js !== false && is_array($js)) {
|
|
|
|
|
|
|
|
|
|
|
660 |
|
661 |
+
# generate url
|
662 |
+
$ind_js_url = fvm_generate_min_url($tag->src, $js['tkey'], 'js', $js['code']);
|
663 |
+
|
664 |
+
# cdn
|
665 |
+
if(isset($fvm_settings['cdn']['jsok']) && $fvm_settings['cdn']['jsok'] == true) {
|
666 |
+
$ind_js_url = fvm_rewrite_cdn_url($ind_js_url);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
667 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
668 |
|
669 |
+
# render block
|
670 |
+
if(isset($tag->async)) { unset($tag->async); }
|
671 |
+
if(isset($tag->defer)) { unset($tag->defer); }
|
672 |
+
|
673 |
+
# http and html preload for render blocking scripts
|
674 |
+
if(!isset($fvm_settings['js']['nopreload']) || (isset($fvm_settings['js']['nopreload']) && $fvm_settings['js']['nopreload'] != true)) {
|
675 |
+
$httppreloads[] = '<'.$ind_js_url.'>; rel=preload; as=script';
|
676 |
+
$htmlpreloads[] = '<link rel="preload" href="'.$ind_js_url.'" as="script" />';
|
677 |
+
}
|
678 |
+
|
679 |
+
# log
|
680 |
+
$size = strlen($js['code']);
|
681 |
+
$js_total = $js_total + $size;
|
682 |
+
$log[] = '[JS Block: '.str_pad(fvm_format_filesize($size), 9,' ',STR_PAD_LEFT).']'."\t".str_replace($fvm_urls['wp_site_url'], '', $js['url']). PHP_EOL;
|
683 |
+
|
684 |
+
# finish early
|
685 |
+
$tag->src = $ind_js_url;
|
686 |
unset($allscripts[$k]);
|
687 |
continue 2;
|
688 |
|
689 |
}
|
|
|
690 |
}
|
691 |
}
|
692 |
}
|
693 |
}
|
694 |
+
|
695 |
+
# force defer
|
|
|
696 |
if(isset($fvm_settings['js']['merge_defer']) && !empty($fvm_settings['js']['merge_defer'])) {
|
697 |
$arr = fvm_string_toarray($fvm_settings['js']['merge_defer']);
|
698 |
if(is_array($arr) && count($arr) > 0) {
|
699 |
+
foreach ($arr as $aa) {
|
700 |
+
if(stripos($tag->src, $aa) !== false) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
701 |
|
702 |
+
# download or fetch from transient, minified
|
703 |
+
$js = fvm_get_js_from_file($tag);
|
704 |
+
if($js !== false && is_array($js)) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
705 |
|
706 |
+
# generate url
|
707 |
+
$ind_js_url = fvm_generate_min_url($tag->src, $js['tkey'], 'js', $js['code']);
|
|
|
|
|
|
|
|
|
708 |
|
709 |
+
# cdn
|
710 |
+
if(isset($fvm_settings['cdn']['jsok']) && $fvm_settings['cdn']['jsok'] == true) {
|
711 |
+
$ind_js_url = fvm_rewrite_cdn_url($ind_js_url);
|
712 |
+
}
|
713 |
+
|
714 |
+
# add defer
|
715 |
+
if(!isset($tag->defer)) { $tag->defer = 'defer'; }
|
716 |
+
|
717 |
+
# log
|
718 |
+
$size = strlen($js['code']);
|
719 |
+
$js_total = $js_total + $size;
|
720 |
+
$log[] = '[JS Defer: '.str_pad(fvm_format_filesize($size), 9,' ',STR_PAD_LEFT).']'."\t".str_replace($fvm_urls['wp_site_url'], '', $js['url']). PHP_EOL;
|
721 |
+
|
722 |
+
# finish early
|
723 |
+
$tag->src = $ind_js_url;
|
724 |
unset($allscripts[$k]);
|
725 |
continue 2;
|
726 |
|
727 |
}
|
|
|
728 |
}
|
729 |
}
|
730 |
}
|
731 |
}
|
732 |
+
|
733 |
+
# remove unprocessed scripts from loop
|
734 |
+
unset($allscripts[$k]);
|
735 |
+
continue;
|
736 |
+
}
|
737 |
+
# END INDIVIDUAL JS MINIFICATION
|
738 |
+
|
739 |
}
|
740 |
+
# END JS FILES
|
741 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
742 |
|
743 |
+
# START INLINED SCRIPTS
|
744 |
+
if(!isset($tag->src)) {
|
745 |
+
|
746 |
+
# remove if empty
|
747 |
+
if(strlen(trim($tag->innertext)) == 0) {
|
748 |
+
$tag->outertext = '';
|
749 |
+
unset($allcss[$k]);
|
750 |
+
continue;
|
751 |
}
|
|
|
|
|
|
|
|
|
|
|
752 |
|
753 |
+
# default
|
754 |
+
$js = ''; $js = $tag->innertext;
|
|
|
755 |
|
756 |
+
# minify?
|
757 |
+
if(!isset($fvm_settings['js']['min_disable_inline']) || (isset($fvm_settings['js']['min_disable_inline'])&& $fvm_settings['js']['min_disable_inline'] != true)) {
|
758 |
+
$js = PHP_EOL . fvm_maybe_minify_js($js, null, true) . PHP_EOL;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
759 |
}
|
|
|
|
|
|
|
|
|
|
|
760 |
|
761 |
+
# delay inline scripts until user interaction (unmergeable)
|
762 |
+
if(isset($fvm_settings['js']['thirdparty']) && !empty($fvm_settings['js']['thirdparty'])) {
|
763 |
+
$arr = fvm_string_toarray($fvm_settings['js']['thirdparty']);
|
764 |
+
if(is_array($arr) && count($arr) > 0) {
|
765 |
+
foreach ($arr as $b) {
|
766 |
+
if(stripos($js, $b) !== false || stripos($js, $b) !== false) {
|
767 |
+
|
768 |
+
# delay
|
769 |
+
$tag->type = 'fvm-script-delay';
|
770 |
+
|
771 |
+
# minified
|
772 |
+
if(!empty($js)) {
|
773 |
+
$tag->innertext = $js;
|
774 |
+
}
|
775 |
+
|
776 |
+
# unset
|
777 |
+
unset($allscripts[$k]);
|
778 |
+
continue 2;
|
779 |
+
}
|
780 |
+
}
|
781 |
+
}
|
782 |
}
|
783 |
+
|
784 |
+
# defer inline scripts
|
785 |
+
if(isset($fvm_settings['js']['defer_dependencies']) && !empty($fvm_settings['js']['defer_dependencies'])) {
|
786 |
+
$arr = fvm_string_toarray($fvm_settings['js']['defer_dependencies']);
|
787 |
+
if(is_array($arr) && count($arr) > 0) {
|
788 |
+
foreach ($arr as $b) {
|
789 |
+
if((stripos($js, $b) !== false || stripos($js, $b) !== false) && !isset($tag->src)) {
|
790 |
+
|
791 |
+
# defer
|
792 |
+
$tag->type = 'module';
|
793 |
+
|
794 |
+
# html comments are not supported inside module scripts
|
795 |
+
if(!empty($js)) {
|
796 |
+
$tag->innertext = preg_replace('/<!--(.|\s)*?-->/ui', '', $js);
|
797 |
+
}
|
798 |
+
|
799 |
+
# unset
|
800 |
+
unset($allscripts[$k]);
|
801 |
+
continue 2;
|
802 |
+
}
|
803 |
+
}
|
804 |
+
}
|
805 |
+
}
|
806 |
}
|
807 |
+
# END INLINED SCRIPTS
|
808 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
809 |
}
|
|
|
810 |
}
|
811 |
+
# END JS LOOP
|
812 |
+
|
813 |
+
|
814 |
+
# START JS LOG
|
815 |
+
if(count($log) > 1) {
|
816 |
+
$log[] = str_pad('-', 21, '-',STR_PAD_LEFT) . PHP_EOL;
|
817 |
+
$log[] = '[JS Total: '.str_pad(fvm_format_filesize($js_total), 9,' ',STR_PAD_LEFT).']' . PHP_EOL;
|
818 |
+
$log[] = str_pad('-', 21, '-',STR_PAD_LEFT);
|
819 |
+
fvm_save_log(array('type'=>'min','msg'=>implode('', $log)));
|
820 |
+
}
|
821 |
+
# END JS LOG
|
822 |
|
823 |
+
# START COMBINING JS
|
824 |
+
|
825 |
+
# header scripts
|
826 |
+
if(is_array($fvm_scripts_header) && count($fvm_scripts_header) > 0) {
|
827 |
|
828 |
+
# merge code, hash
|
829 |
+
$merged_js = implode(PHP_EOL, $fvm_scripts_header);
|
830 |
+
$tkey = fvm_generate_hash_with_prefix(hash('sha256', $merged_js), 'js');
|
831 |
+
|
832 |
+
# generate url
|
833 |
+
$merged_js_url = fvm_generate_min_url('combined', $tkey, 'js', $merged_js);
|
834 |
+
|
835 |
+
# cdn
|
836 |
+
if(isset($fvm_settings['cdn']['jsok']) && $fvm_settings['cdn']['jsok'] == true) {
|
837 |
+
$merged_js_url = fvm_rewrite_cdn_url($merged_js_url);
|
838 |
}
|
839 |
|
840 |
+
# http and html preload for render blocking scripts
|
841 |
+
if(!isset($fvm_settings['js']['nopreload']) || (isset($fvm_settings['js']['nopreload']) && $fvm_settings['js']['nopreload'] != true)) {
|
842 |
+
$httppreloads[] = '<'.$merged_js_url.'>; rel=preload; as=script';
|
843 |
+
$htmlpreloads[] = '<link rel="preload" href="'.$merged_js_url.'" as="script" />';
|
|
|
844 |
}
|
845 |
|
846 |
+
# add to header
|
847 |
+
$htmljsheader[] = "<script data-cfasync='false' src='".$merged_js_url."'></script>";
|
848 |
+
|
849 |
}
|
850 |
|
851 |
+
# deferred scripts
|
852 |
+
if(is_array($fvm_scripts_defer) && count($fvm_scripts_defer) > 0) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
853 |
|
854 |
+
# merge code, hash
|
855 |
+
$merged_js = implode(PHP_EOL, $fvm_scripts_defer);
|
856 |
+
$tkey = fvm_generate_hash_with_prefix(hash('sha256', $merged_js), 'js');
|
857 |
+
|
858 |
+
# generate url
|
859 |
+
$merged_js_url = fvm_generate_min_url('combined', $tkey, 'js', $merged_js);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
860 |
|
861 |
+
# cdn
|
862 |
+
if(isset($fvm_settings['cdn']['jsok']) && $fvm_settings['cdn']['jsok'] == true) {
|
863 |
+
$merged_js_url = fvm_rewrite_cdn_url($merged_js_url);
|
|
|
|
|
|
|
|
|
|
|
864 |
}
|
865 |
+
|
866 |
+
# header, no preload for deferred files
|
867 |
+
$htmljsheader[] = "<script defer='defer' src='".$merged_js_url."'></script>";
|
868 |
|
|
|
|
|
|
|
|
|
|
|
869 |
}
|
870 |
|
871 |
+
}
|
872 |
+
# END JS PROCESSING
|
873 |
+
|
874 |
+
|
875 |
+
|
876 |
+
# process HTML minification, if not disabled ###############################
|
877 |
+
if(fvm_can_process_html()) {
|
878 |
+
|
879 |
+
# Remove HTML comments and IE conditionals
|
880 |
+
if(isset($fvm_settings['html']['nocomments']) && $fvm_settings['html']['nocomments'] == true) {
|
881 |
+
foreach($html->find('comment') as $element) {
|
882 |
+
$element->outertext = '';
|
883 |
}
|
884 |
}
|
885 |
|
886 |
+
# Remove generator tags
|
887 |
+
if(isset($fvm_settings['html']['cleanup_header']) && $fvm_settings['html']['cleanup_header'] == true) {
|
888 |
+
|
889 |
+
# remove
|
890 |
+
foreach($html->find('head meta[name=generator], head link[rel=shortlink], head link[rel=dns-prefetch], head link[rel=preconnect], head link[rel=prefetch], head link[rel=prerender], head meta[name*=msapplication], head link[rel=apple-touch-icon], head link[rel=EditURI], head link[rel=preconnect], head link[rel=wlwmanifest], head link[rel=https://api.w.org/], head link[href*=/wp-json/], head link[rel=pingback], head link[type=application/json+oembed], head link[type=text/xml+oembed]') as $element) {
|
891 |
+
$element->outertext = '';
|
892 |
}
|
893 |
+
|
894 |
+
# allow only the last link[rel=icon]
|
895 |
+
$ic = array(); $ic = $html->find('head link[rel=icon]');
|
896 |
+
$i = 1; $len = count($ic);
|
897 |
+
if($len > 1) {
|
898 |
+
foreach($ic as $element) {
|
899 |
+
if ($i != $len) { $element->outertext = ''; } $i++; # delete except if last
|
900 |
+
}
|
901 |
}
|
902 |
}
|
903 |
+
|
904 |
+
}
|
905 |
+
|
906 |
+
# build extra head and footer ###############################
|
907 |
+
|
908 |
+
# header and footer markers
|
909 |
+
$hm = '<!-- h_preheader --><!-- h_header_function -->';
|
910 |
+
$hm_late = '<!-- h_cssheader --><!-- h_jsheader -->';
|
911 |
+
$fm = '<!-- h_footer_fvm_scripts -->';
|
912 |
+
|
913 |
+
# add our function to head
|
914 |
+
if(fvm_can_minify_css() || fvm_can_minify_js()) {
|
915 |
+
$hm = fvm_add_header_function($hm);
|
916 |
+
}
|
917 |
|
918 |
+
# remove charset meta tag and collect it to first position
|
919 |
+
if(!is_null($html->find('meta[charset]', 0))) {
|
920 |
+
$hm = str_replace('<!-- h_preheader -->', $html->find('meta[charset]', 0)->outertext.'<!-- h_preheader -->', $hm);
|
921 |
+
foreach($html->find('meta[charset]') as $element) { $element->outertext = ''; }
|
922 |
+
}
|
923 |
+
|
924 |
+
# remove other meta tag and collect them between preload and css/js files
|
925 |
+
foreach($html->find('head meta, head title, head link[rel=canonical], head link[rel=alternate], head link[rel=pingback], head script[type=application/ld+json]') as $element) {
|
926 |
+
$hm_late = str_replace('<!-- h_cssheader -->', $element->outertext.'<!-- h_cssheader -->', $hm_late);
|
927 |
+
$element->outertext = '';
|
928 |
+
}
|
929 |
+
|
930 |
+
# preload headers, by importance
|
931 |
+
if(is_array($htmlpreloads) || is_array($httppreloads)) {
|
932 |
|
933 |
+
# deduplicate
|
934 |
+
$htmlpreloads = array_unique($htmlpreloads);
|
935 |
+
$httppreloads = array_unique($httppreloads);
|
936 |
|
937 |
+
# get values
|
938 |
+
$pre_html = array_values($htmlpreloads);
|
939 |
+
$pre_http = array_values($httppreloads);
|
940 |
+
|
941 |
+
# add preload http header
|
942 |
+
if(count($pre_http) > 0) {
|
943 |
+
if(!headers_sent()) {
|
944 |
+
header("Link: " . implode(', ', $pre_http));
|
945 |
}
|
946 |
}
|
947 |
|
948 |
+
# add preload html header
|
949 |
+
if(count($pre_html) > 0) {
|
950 |
+
$hm = str_replace('<!-- h_preheader -->', implode(PHP_EOL, $pre_html).'<!-- h_preheader -->', $hm);
|
|
|
|
|
|
|
951 |
}
|
952 |
|
953 |
}
|
954 |
|
955 |
+
# add stylesheets
|
956 |
+
if(isset($htmlcssheader)) {
|
957 |
+
if(is_array($htmlcssheader) && count($htmlcssheader) > 0) {
|
958 |
+
ksort($htmlcssheader); # priority
|
959 |
+
$hm_late = str_replace('<!-- h_cssheader -->', implode(PHP_EOL, $htmlcssheader).'<!-- h_cssheader -->', $hm_late);
|
960 |
+
}
|
961 |
+
}
|
962 |
+
|
963 |
+
# add header scripts
|
964 |
+
if(isset($htmljsheader)) {
|
965 |
+
if(is_array($htmljsheader) && count($htmljsheader) > 0) {
|
966 |
+
ksort($htmljsheader); # priority
|
967 |
+
$hm_late = str_replace('<!-- h_jsheader -->', implode(PHP_EOL, $htmljsheader).'<!-- h_jsheader -->', $hm_late);
|
968 |
+
}
|
969 |
+
}
|
970 |
+
|
971 |
+
# add defer scripts
|
972 |
+
if(isset($htmljscodedefer)) {
|
973 |
+
if(is_array($htmljscodedefer) && count($htmljscodedefer) > 0) {
|
974 |
+
ksort($htmljscodedefer); # priority
|
975 |
+
$hm_late = str_replace('<!-- h_jsheader -->', implode(PHP_EOL, $htmljscodedefer), $hm_late);
|
976 |
+
}
|
977 |
+
}
|
978 |
+
|
979 |
+
# add fvm_footer scripts, if enabled
|
980 |
+
if(fvm_can_minify_js()) {
|
981 |
+
$fm = fvm_add_delay_scripts_logic($fm);
|
982 |
+
}
|
983 |
+
|
984 |
+
# cleanup leftover markers
|
985 |
+
$hm = str_replace(array('<!-- h_preheader -->', '<!-- h_header_function -->'), '', $hm);
|
986 |
+
$hm_late = str_replace(array('<!-- h_cssheader -->', '<!-- h_jsheader -->'), '', $hm_late);
|
987 |
+
$fm = str_replace('<!-- h_footer_fvm_scripts -->', '', $fm);
|
988 |
+
|
989 |
+
# append header and footer
|
990 |
+
if(!is_null($html->find('head', 0)) && !is_null($html->find('body', -1))) {
|
991 |
+
if(!is_null($html->find('head', 0)->first_child()) && !is_null($html->find('body', -1)->last_child())) {
|
992 |
+
$html->find('head', 0)->first_child()->outertext = $hm . $html->find('head', 0)->first_child()->outertext . $hm_late;
|
993 |
+
$html->find('body', -1)->last_child()->outertext = $html->find('body', -1)->last_child ()->outertext . $fm;
|
994 |
+
}
|
995 |
+
}
|
996 |
+
|
997 |
+
|
998 |
+
# convert html object to string, save all objects to string
|
999 |
+
$html = trim($html->save());
|
1000 |
+
|
1001 |
+
# process cdn optimization
|
1002 |
+
if(fvm_can_process_cdn()) {
|
1003 |
+
$html = fvm_process_cdn($html);
|
1004 |
+
}
|
1005 |
+
|
1006 |
+
# minify remaining HTML at the end, if enabled
|
1007 |
+
if(fvm_can_process_html()) {
|
1008 |
+
if(!isset($fvm_settings['html']['min_disable']) || (isset($fvm_settings['html']['min_disable']) && $fvm_settings['html']['min_disable'] != true)) {
|
1009 |
+
$html = fvm_raisermin_html($html);
|
1010 |
+
}
|
1011 |
+
}
|
1012 |
+
|
1013 |
+
# filter final html if needed
|
1014 |
+
if(function_exists('fvm_filter_final_html')) {
|
1015 |
+
$html = fvm_filter_final_html($html);
|
1016 |
+
}
|
1017 |
+
|
1018 |
# return html
|
1019 |
return $html;
|
1020 |
|
layout/admin-layout-help.php
CHANGED
@@ -9,8 +9,8 @@
|
|
9 |
<div>
|
10 |
<p><strong>Notes:</strong></p>
|
11 |
<p>JavaScript merging functionality went through a significant change on FVM 3 and it now requires manual configuration to work.</p>
|
12 |
-
<p>If you are upgrading from FVM 2 please refer to the help section below
|
13 |
-
<p>If you just installed the plugin, please note that JS is not being optimized yet. You have to choose which files to be render blocking and which ones to be deferred, plus it's dependencies (if any). </p>
|
14 |
<p>Previously, FVM merged everything and relied on having options to ignore scripts. This option frequently created issues with other plugin updates, when they changed something JavaScript related.</p>
|
15 |
<p>Please understand that this plugin is and it has always been aimed at being a tool for advanced users and developers, so it's not meant just be plug and play, without manual settings in place.</p>
|
16 |
<p>There is a new method to optimize third party scripts and load them on user interaction or automatically, after 5 seconds. This is a more recommended method to optimize scripts, as compared to FVM 2 which used document.write and other deprecated methods.</p>
|
@@ -45,17 +45,9 @@
|
|
45 |
<h3>Purge Minified CSS/JS files instantly</h3>
|
46 |
<div>
|
47 |
<p><strong>Notes:</strong></p>
|
48 |
-
<p>
|
49 |
-
|
50 |
-
|
51 |
-
<div>
|
52 |
-
<p><strong>Notes:</strong></p>
|
53 |
-
<p>When you are testing things, sometimes you may want to preserve all FVM settings when you uninstall or delete the plugin.</p>
|
54 |
-
</div>
|
55 |
-
<h3>Force HTTPS urls on merged files</h3>
|
56 |
-
<div>
|
57 |
-
<p><strong>Notes:</strong></p>
|
58 |
-
<p>This will make sure that when FVM generates a CSS and JS file, that it's linked on your page with https.</p>
|
59 |
</div>
|
60 |
</div>
|
61 |
|
@@ -68,27 +60,27 @@
|
|
68 |
<p><strong>Notes:</strong></p>
|
69 |
<p>You need to enable this option, for any other options in the HTML section to work.</p>
|
70 |
</div>
|
71 |
-
<h3>Disable HTML Minification</h3>
|
72 |
-
<div>
|
73 |
-
<p><strong>Notes:</strong></p>
|
74 |
-
<p>Although rare, it's possible that HTML minification may strip too much code thus breaking something.</p>
|
75 |
-
<p>You can use this option to test if that is the case.</p>
|
76 |
-
</div>
|
77 |
<h3>Strip HTML Comments</h3>
|
78 |
<div>
|
79 |
<p><strong>Notes:</strong></p>
|
80 |
-
<p>Some plugins may need to use comments for certain functionality to work, however this is quite rare.
|
81 |
</div>
|
82 |
<h3>Cleanup Header</h3>
|
83 |
<div>
|
84 |
<p><strong>Notes:</strong></p>
|
85 |
-
<p>This options removes resource hints, generator
|
86 |
-
<p>
|
87 |
</div>
|
88 |
<h3>Remove Emoji</h3>
|
89 |
<div>
|
90 |
<p><strong>Notes:</strong></p>
|
91 |
-
<p>This will remove the default emoji scripts from wordpress, thus reducing the amount of code during page loading.</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
92 |
</div>
|
93 |
</div>
|
94 |
|
@@ -102,47 +94,52 @@
|
|
102 |
<p><strong>Notes:</strong></p>
|
103 |
<p>You need to enable this option, for any other options in the CSS section to work.</p>
|
104 |
</div>
|
105 |
-
<h3>
|
106 |
<div>
|
107 |
<p><strong>Notes:</strong></p>
|
108 |
-
<p>
|
109 |
</div>
|
110 |
-
<h3>
|
111 |
<div>
|
112 |
<p><strong>Notes:</strong></p>
|
113 |
-
<p>
|
114 |
-
<p>If your CSS files combined are large, inlining it will delay the time needed for the first byte, as you are forcing the server to compress the HTML and the CSS on the same process.</p>
|
115 |
</div>
|
116 |
-
<h3>
|
117 |
<div>
|
118 |
<p><strong>Notes:</strong></p>
|
119 |
-
<p>
|
120 |
</div>
|
121 |
-
<h3>
|
122 |
<div>
|
123 |
<p><strong>Notes:</strong></p>
|
124 |
-
<p>
|
125 |
-
<p>It may be useful for debugging purposes or to evaluate how many fonts are in use.</p>
|
126 |
</div>
|
127 |
-
<h3>
|
128 |
<div>
|
129 |
<p><strong>Notes:</strong></p>
|
130 |
-
<p>
|
131 |
-
|
|
|
|
|
|
|
|
|
|
|
132 |
</div>
|
133 |
<h3>Ignore CSS files</h3>
|
134 |
<div>
|
135 |
<p><strong>Notes:</strong></p>
|
136 |
-
<p>
|
137 |
-
|
138 |
-
|
|
|
|
|
|
|
139 |
</div>
|
140 |
-
<h3>
|
141 |
<div>
|
142 |
<p><strong>Notes:</strong></p>
|
143 |
-
<p>
|
144 |
-
<p>
|
145 |
-
<p>You should still first try to remove it or dequeue it with PHP code, when possible.</p>
|
146 |
</div>
|
147 |
</div>
|
148 |
|
@@ -156,47 +153,50 @@
|
|
156 |
<p><strong>Notes:</strong></p>
|
157 |
<p>You need to enable this option, for any other options in the JS section to work.</p>
|
158 |
</div>
|
159 |
-
<h3>
|
160 |
<div>
|
161 |
<p><strong>Notes:</strong></p>
|
162 |
-
<p>
|
163 |
-
<p>You can use this option to test if that is the case.</p>
|
164 |
</div>
|
165 |
-
<h3>
|
166 |
<div>
|
167 |
<p><strong>Notes:</strong></p>
|
168 |
-
<p>
|
169 |
-
<p>You must check your browser console log in incognito mode, for possible errors after enabling this feature. Sometimes there are no errors but some scripts may not work as well, so use this feature with care.</p>
|
170 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
171 |
<h3>Ignore Script Files</h3>
|
172 |
<div>
|
173 |
<p><strong>Notes:</strong></p>
|
174 |
-
<p>When you are
|
175 |
-
<p>This should be empty by default, and only used strictly when a CSS being merged is breaking the page layout.</p>
|
176 |
</div>
|
177 |
-
<h3>
|
178 |
<div>
|
179 |
<p><strong>Notes:</strong></p>
|
180 |
-
<p>In most WordPress themes and for a significant amount of plugins, you need to render block jQuery and
|
181 |
-
<p>
|
182 |
-
<p>It's important for speed, that you keep this section to a bare minimum, usually, jQuery and jQuery migrate only.</p>
|
183 |
-
<p>Some plugins such as gravity forms may also require to be render blocking, so you should look out for browser console log errors in incognito mode.</p>
|
184 |
<p><strong>Recommended Default Settings:</strong></p>
|
185 |
<p class="fvm-code-full">
|
186 |
-
/jquery-migrate
|
187 |
-
/jquery-migrate.js<br>
|
188 |
-
/jquery-migrate.min.js<br>
|
189 |
/jquery.js<br>
|
190 |
/jquery.min.js<br>
|
191 |
</p>
|
192 |
</div>
|
193 |
-
<h3>
|
194 |
<div>
|
195 |
<p><strong>Notes:</strong></p>
|
196 |
-
<p>
|
197 |
-
<p>
|
198 |
-
<p>You must check your browser console log in incognito mode, for possible errors after enabling this feature, and either move them to the header, remove them from this list (be more specific with paths so it doesn't match certain files), or use the Inline JavaScript Dependencies section, to force inline scripts to wait for this file to load.</p>
|
199 |
-
<p>Note that this is an advanced feature that can stop your scripts from working, hence it requires manual configuration.</p>
|
200 |
<p><strong>Recommended Default Settings:</strong></p>
|
201 |
<p class="fvm-code-full">
|
202 |
/ajax.aspnetcdn.com/ajax/<br>
|
@@ -208,24 +208,27 @@
|
|
208 |
/wp-includes/
|
209 |
</p>
|
210 |
</div>
|
211 |
-
<h3>Inline JavaScript
|
212 |
<div>
|
213 |
<p><strong>Notes:</strong></p>
|
214 |
-
<p>
|
215 |
-
<p>
|
216 |
-
<p>
|
217 |
-
<p>
|
218 |
-
<p
|
|
|
|
|
|
|
|
|
|
|
|
|
219 |
</div>
|
220 |
-
<h3>
|
221 |
<div>
|
222 |
<p><strong>Notes:</strong></p>
|
223 |
-
<p>Scripts like analytics, ads, tracking codes, etc, consume important CPU and
|
224 |
-
<p>
|
225 |
-
<p>
|
226 |
-
<p>FVM will delay most Async and Defer scripts, a well as inline code matching these settings.</p>
|
227 |
-
<p>You can rewrite most scripts to support this feature by adding the Async or Defer attribute, however, note that if you blindly use this method for render blocking scripts, it may trigger "undefined" errors on the browser console log or some elements may stop working (some scripts only work in render blocking mode).</p>
|
228 |
-
<p>If you have render blocking third party scripts, ask your provider if they can provide you with an async implementation (else remove them, because render blocking scripts are not recommended for speed).</p>
|
229 |
<p><strong>Example Settings:</strong></p>
|
230 |
<p class="fvm-code-full">
|
231 |
function(w,d,s,l,i)<br>
|
@@ -239,9 +242,7 @@
|
|
239 |
<h3>Remove JavaScript Scripts</h3>
|
240 |
<div>
|
241 |
<p><strong>Notes:</strong></p>
|
242 |
-
<p>This
|
243 |
-
<p>It can be used when you want to remove some JS file that you cannot remove directly from the source.</p>
|
244 |
-
<p>If it's a third party script you added to the header or footer (or via some plugin), it's better if you delete it at the source.</p>
|
245 |
</div>
|
246 |
</div>
|
247 |
|
@@ -273,42 +274,14 @@
|
|
273 |
<h3>CDN URL</h3>
|
274 |
<div>
|
275 |
<p><strong>Notes:</strong></p>
|
276 |
-
<p>This is not required for providers such as
|
277 |
-
<p>For other types of CDN, you are usually provided with an alternative domain name from where your static files can be served
|
278 |
</div>
|
279 |
<h3>CDN Integration</h3>
|
280 |
<div>
|
281 |
<p><strong>Notes:</strong></p>
|
282 |
-
<p>Uses syntax from <a target="_blank" href="https://simplehtmldom.sourceforge.io/manual.htm">https://simplehtmldom.sourceforge.io/manual.htm</a> for modifying the
|
283 |
-
<p>The plugin will
|
284 |
-
<p><strong>Recommended Default Settings:</strong></p>
|
285 |
-
<p class="fvm-code-full">
|
286 |
-
a[data-interchange*=/wp-content/]<br>
|
287 |
-
image[height]<br>
|
288 |
-
img[src*=/wp-content/], img[data-src*=/wp-content/], img[data-srcset*=/wp-content/]<br>
|
289 |
-
link[rel=icon]<br>
|
290 |
-
picture source[srcset*=/wp-content/]<br>
|
291 |
-
video source[type*=video]
|
292 |
-
</p>
|
293 |
-
</div>
|
294 |
-
</div>
|
295 |
-
|
296 |
-
|
297 |
-
<div style="height: 20px;"></div>
|
298 |
-
<h2 class="title">Cache Settings</h2>
|
299 |
-
|
300 |
-
<div class="accordion">
|
301 |
-
<h3>Public Cache Path</h3>
|
302 |
-
<div>
|
303 |
-
<p><strong>Notes:</strong></p>
|
304 |
-
<p>This can be any writeable directory or mounting point on your server, as long as it's mapped to be served on publicly available URL.</p>
|
305 |
-
<p>Should be left empty by default, unless your hosting blocks writing files to the default cache directory.</p>
|
306 |
-
</div>
|
307 |
-
<h3>Public Cache URL</h3>
|
308 |
-
<div>
|
309 |
-
<p><strong>Notes:</strong></p>
|
310 |
-
<p>This must be a publicly available URL on your site, where users can download the generated js/css files.</p>
|
311 |
-
<p>Should be left empty by default, unless your hosting blocks writing files to the default cache directory.</p>
|
312 |
</div>
|
313 |
</div>
|
314 |
|
@@ -369,15 +342,15 @@
|
|
369 |
<div>
|
370 |
<p><strong>Notes:</strong></p>
|
371 |
<p>Simply disable the plugin, and make sure to purge all page caches (Cache Plugins, Hosting, OPCache, etc).</p>
|
372 |
-
<p>Note that some hosts rate limit the amount of times you can purge caches to once every few minutes, so you may be purging and it doesn't work, because you are being rate limited by your hosting cache system. If that happens,
|
|
|
373 |
<p>FVM does not modify your site. It runs after your template loads and filters the final HTML to present it to your users, in a more optimized way.</p>
|
374 |
</div>
|
375 |
<h3>I have disabled FVM but somehow the cache files are still being generated?</h3>
|
376 |
<div>
|
377 |
<p><strong>Notes:</strong></p>
|
378 |
-
<p>If you have
|
379 |
-
<p>
|
380 |
-
<p>A few hosting providers will cache your disk in memory to speed things up when they use remote disk locations, which may cause code to be cached even if you have deleted it completely from the disk. In that case, restart the server or ask your hosting to purge all disk caches.</p>
|
381 |
</div>
|
382 |
<h3>Where can I get support or ask questions about the plugin?</h3>
|
383 |
<div>
|
@@ -387,10 +360,10 @@
|
|
387 |
<h3>How is it possible that some scan is showing malware on the plugin?</h3>
|
388 |
<div>
|
389 |
<p><strong>Notes:</strong></p>
|
390 |
-
<p>I guarantee that the plugin is 100% clean of malware, provided you have downloaded the plugin from the official WordPress source.</p>
|
391 |
-
<p>
|
392 |
-
<p>
|
393 |
-
<p>If you are seeing malware on any file related to FVM, simply delete the plugin
|
394 |
</div>
|
395 |
<h3>How do I report a security issue or file a bug report?</h3>
|
396 |
<div>
|
9 |
<div>
|
10 |
<p><strong>Notes:</strong></p>
|
11 |
<p>JavaScript merging functionality went through a significant change on FVM 3 and it now requires manual configuration to work.</p>
|
12 |
+
<p>If you are upgrading from FVM 2 please refer to the help section below for more information on the settings.</p>
|
13 |
+
<p>If you just installed the plugin, please note that JS is not being optimized yet. You have to choose which files to be render blocking and which ones to be deferred, plus it's inline script dependencies (if any). </p>
|
14 |
<p>Previously, FVM merged everything and relied on having options to ignore scripts. This option frequently created issues with other plugin updates, when they changed something JavaScript related.</p>
|
15 |
<p>Please understand that this plugin is and it has always been aimed at being a tool for advanced users and developers, so it's not meant just be plug and play, without manual settings in place.</p>
|
16 |
<p>There is a new method to optimize third party scripts and load them on user interaction or automatically, after 5 seconds. This is a more recommended method to optimize scripts, as compared to FVM 2 which used document.write and other deprecated methods.</p>
|
45 |
<h3>Purge Minified CSS/JS files instantly</h3>
|
46 |
<div>
|
47 |
<p><strong>Notes:</strong></p>
|
48 |
+
<p>When you purge CSS/JS files instantly, all CSS and JS cache files are deleted immediately when you clear everything on FVM. While this is great during development, it may cause issues when your hosting is doing page caching that cannot be purged by FVM. For example, if you were to delete the CSS and JS files instantly without purging the full page cache, that page cache would now be pointing to deleted files.</p>
|
49 |
+
<p>If you deselect this option, whenever you clear everything on FVM, it will only try to delete files that are older than 24h (and hopefully this should be enough for your hosting to expire the page cache automatically). That way, even if your hosting is still showing your page cache to anonymous users, the referred CSS and JS files will still be available.</p>
|
50 |
+
<p>If you are not sure about page caching on your server or hosting provider, you should keep this option disabled.</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
51 |
</div>
|
52 |
</div>
|
53 |
|
60 |
<p><strong>Notes:</strong></p>
|
61 |
<p>You need to enable this option, for any other options in the HTML section to work.</p>
|
62 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
63 |
<h3>Strip HTML Comments</h3>
|
64 |
<div>
|
65 |
<p><strong>Notes:</strong></p>
|
66 |
+
<p>Some plugins may need to use comments for certain functionality to work, however this is quite rare. The benefit of removing comments is usually very small, so if needed you can disable this setting.</p>
|
67 |
</div>
|
68 |
<h3>Cleanup Header</h3>
|
69 |
<div>
|
70 |
<p><strong>Notes:</strong></p>
|
71 |
+
<p>This options removes resource hints, generator tags, shortlinks, manifest link, etc from the header.</p>
|
72 |
+
<p>The header should be kept as lean as possible for the best TTFB response times and LCP metrics, but if you later find that you need some of the stuff that is removed by this option, you can disable this setting.</p>
|
73 |
</div>
|
74 |
<h3>Remove Emoji</h3>
|
75 |
<div>
|
76 |
<p><strong>Notes:</strong></p>
|
77 |
+
<p>This will remove the default emoji scripts from wordpress, thus reducing the amount of code during page loading. If you use WordPress emoji when posting content, you should keep this option disabled.</p>
|
78 |
+
</div>
|
79 |
+
<h3>Disable HTML Minification</h3>
|
80 |
+
<div>
|
81 |
+
<p><strong>Notes:</strong></p>
|
82 |
+
<p>Although rare, it's possible for the HTML minification to strip too much code thus breaking something. You can use this option to test if that is the case and keep this option disabled if that is the case.</p>
|
83 |
+
<p>HTML minification is no longer a recommendation by gtmetrix or pagespeed insights, so you can keep this option disabled if there is any incompatibility issue.</p>
|
84 |
</div>
|
85 |
</div>
|
86 |
|
94 |
<p><strong>Notes:</strong></p>
|
95 |
<p>You need to enable this option, for any other options in the CSS section to work.</p>
|
96 |
</div>
|
97 |
+
<h3>Merge Fonts and Icons Separately</h3>
|
98 |
<div>
|
99 |
<p><strong>Notes:</strong></p>
|
100 |
+
<p>This will try to collect and simplify all your CSS font face rules into a separate CSS file and load it async. It may be useful for de-duplication of fonts, or to evaluate how many fonts are in use. </p>
|
101 |
</div>
|
102 |
+
<h3>Remove "Print" stylesheets</h3>
|
103 |
<div>
|
104 |
<p><strong>Notes:</strong></p>
|
105 |
+
<p>As a generic rule this it's safe to remove it for the vast majority of sites, unless your users often need to print pages from your site and you have customized styles for when they do so.</p>
|
|
|
106 |
</div>
|
107 |
+
<h3>Combine CSS Files</h3>
|
108 |
<div>
|
109 |
<p><strong>Notes:</strong></p>
|
110 |
+
<p>Merging CSS is no longer recommended if your server supports HTTP/2. The feature also usually causes conflicts when merging multiple CSS files into one, due to the lack of specificity or other errors in the code. It's still available for legacy support on old installations or outdated servers that do not support HTTP/2 delivery.</p>
|
111 |
</div>
|
112 |
+
<h3>Disable CSS Files Minification</h3>
|
113 |
<div>
|
114 |
<p><strong>Notes:</strong></p>
|
115 |
+
<p>Although rare, it's possible that CSS files minification may strip too much code and break some style rules that are not supported by the minification library. You can always try to disable this and check if this fixes anything, then use the ignore list to exclude the file that is causing issues.</p>
|
|
|
116 |
</div>
|
117 |
+
<h3>Disable CSS Styles Minification</h3>
|
118 |
<div>
|
119 |
<p><strong>Notes:</strong></p>
|
120 |
+
<p>Although rare, it's possible that CSS Styles minification may strip too much code and break some style rules that are not supported by the minification library. You can always try to disable this and check if this fixes anything.</p>
|
121 |
+
</div>
|
122 |
+
<h3>Disable CSS Link Preload</h3>
|
123 |
+
<div>
|
124 |
+
<p><strong>Notes:</strong></p>
|
125 |
+
<p>CSS Link Preloading is useful when you are merging CSS files or when you defined certain paths as Async CSS. By default, FVM will send an HTTP preload request as well as adding the html preload tag on the header, which will prioritize downloading the critical styles earlier than the other resources.</p>
|
126 |
+
<p>If you select this option, these headers will be removed and your default preload resources will load earlier than the CSS files. You need to test and see what works best for you.</p>
|
127 |
</div>
|
128 |
<h3>Ignore CSS files</h3>
|
129 |
<div>
|
130 |
<p><strong>Notes:</strong></p>
|
131 |
+
<p>If there is a conflict when merging CSS files or during individual minification of a specific CSS file, you can add the path on this section and FVM will ignore the file, thus leaving it alone.</p>
|
132 |
+
</div>
|
133 |
+
<h3>Remove CSS Files</h3>
|
134 |
+
<div>
|
135 |
+
<p><strong>Notes:</strong></p>
|
136 |
+
<p>If your plugins enqueue multiple duplicate libraries with different url paths, you can add the path on this section and FVM will remove the file from the frontend, thus reducing your total CSS size.</p>
|
137 |
</div>
|
138 |
+
<h3>Async CSS Files</h3>
|
139 |
<div>
|
140 |
<p><strong>Notes:</strong></p>
|
141 |
+
<p>CSS files from plugins that are not rendered above the fold, should ideally be loaded async. For example, if a plugin has CSS files but you only use the element on the footer, you could add the /plugins/plugin-name/ here to async it. But you should not async CSS files that are needed for content that is visible on the critical path.</p>
|
142 |
+
<p>Also note that by loading certain CSS files async, you are changing the order of styles. This means, some styles may or may not work as intended, because now they load on a different position.</p>
|
|
|
143 |
</div>
|
144 |
</div>
|
145 |
|
153 |
<p><strong>Notes:</strong></p>
|
154 |
<p>You need to enable this option, for any other options in the JS section to work.</p>
|
155 |
</div>
|
156 |
+
<h3>Combine JS Files</h3>
|
157 |
<div>
|
158 |
<p><strong>Notes:</strong></p>
|
159 |
+
<p>Merging JS is no longer recommended if your server supports HTTP/2. The feature also usually causes conflicts when merging multiple JS files into one, due to a different order of loading or other errors in the code. It's still available for legacy support on old installations or outdated servers that do not support HTTP/2 delivery.</p>
|
|
|
160 |
</div>
|
161 |
+
<h3>Disable JS Files Minification</h3>
|
162 |
<div>
|
163 |
<p><strong>Notes:</strong></p>
|
164 |
+
<p>JS files minification may strip too much code and break some code that is not supported by the minification library. You can always try to disable this and check if this fixes anything, then use the ignore list to exclude the file that is causing issues.</p>
|
|
|
165 |
</div>
|
166 |
+
<h3>Disable JS Inline Minification</h3>
|
167 |
+
<div>
|
168 |
+
<p><strong>Notes:</strong></p>
|
169 |
+
<p>Inline JS Styles minification may strip too much code and break some code that is not supported by the minification library. You can always try to disable this and check if this fixes anything.</p>
|
170 |
+
</div>
|
171 |
+
<h3>Disable JS Link Preload</h3>
|
172 |
+
<div>
|
173 |
+
<p><strong>Notes:</strong></p>
|
174 |
+
<p>JS Link Preloading is useful when you are merging JS files or when you defined certain paths as Defer JS. By default, FVM will send an HTTP preload request as well as adding the html preload tag on the header, which will prioritize downloading the render blocking scripts earlier than the other resources.</p>
|
175 |
+
<p>If you select this option, these headers will be removed and your default preload resources will load earlier than the JS files. You need to test and see what works best for you.</p>
|
176 |
+
</div>
|
177 |
+
|
178 |
<h3>Ignore Script Files</h3>
|
179 |
<div>
|
180 |
<p><strong>Notes:</strong></p>
|
181 |
+
<p>When you are merging JS files, the order of scripts change positions and dependencies may break. Other times, a specific script is not supported by the minification and breaks as well. If you encounter issues while merging or minifying JS files, you can exclude them here and those files will be left alone.</p>
|
|
|
182 |
</div>
|
183 |
+
<h3>Render Blocking JS files</h3>
|
184 |
<div>
|
185 |
<p><strong>Notes:</strong></p>
|
186 |
+
<p>In most WordPress themes and for a significant amount of plugins, you usually need to render block jQuery and jQuery Migrate for compatibility reasons.</p>
|
187 |
+
<p>Some plugins may not work at all if they are not render blocking, so you should look out for browser console log errors in incognito mode.</p>
|
|
|
|
|
188 |
<p><strong>Recommended Default Settings:</strong></p>
|
189 |
<p class="fvm-code-full">
|
190 |
+
/jquery-migrate<br>
|
|
|
|
|
191 |
/jquery.js<br>
|
192 |
/jquery.min.js<br>
|
193 |
</p>
|
194 |
</div>
|
195 |
+
<h3>Defer JS Files</h3>
|
196 |
<div>
|
197 |
<p><strong>Notes:</strong></p>
|
198 |
+
<p>Deferring every single script is not always the best solution, especially if those are needed to generate content above the fold. You must check your browser console log in incognito mode for possible errors after enabling this feature, and either move them to the render blocking section or check if there is any inline script that also needs to be deferred (so the order of loading is preserved).</p>
|
199 |
+
<p>Note that this is an advanced feature, hence it requires manual configuration for it to work.</p>
|
|
|
|
|
200 |
<p><strong>Recommended Default Settings:</strong></p>
|
201 |
<p class="fvm-code-full">
|
202 |
/ajax.aspnetcdn.com/ajax/<br>
|
208 |
/wp-includes/
|
209 |
</p>
|
210 |
</div>
|
211 |
+
<h3>Defer Inline JavaScript</h3>
|
212 |
<div>
|
213 |
<p><strong>Notes:</strong></p>
|
214 |
+
<p>When you merge JS files and defer them, you are effectively changing the order in which they load, however for certain scripts, the order of loading matters. If you are deferring a certain JS file and you see an "undefined" error triggered on some inline code, you can try this option to also defer the inline code and preserve the order of execution.</p>
|
215 |
+
<p>Note however, not all scripts can work with defer so you need to test if everything is working without errors.</p>
|
216 |
+
<p>This is empty by default, unless you determine that it's needed.</p>
|
217 |
+
<p><strong>Recommended Default Settings:</strong></p>
|
218 |
+
<p class="fvm-code-full">
|
219 |
+
wp.i18n<br>
|
220 |
+
wp.apiFetch.use<br>
|
221 |
+
window.lodash<br>
|
222 |
+
wp.hooks<br>
|
223 |
+
wp.url
|
224 |
+
</p>
|
225 |
</div>
|
226 |
+
<h3>Delay third party scripts until user interaction</h3>
|
227 |
<div>
|
228 |
<p><strong>Notes:</strong></p>
|
229 |
+
<p>Scripts like analytics, ads, tracking codes, etc, consume important CPU and network resources needed for the initial page view. You can force certain plugins to wait for user interaction (mouseover, keydown, touchstart, touchmove and wheel) and the scripts will only run on these events.</p>
|
230 |
+
<p>Delaying these scripts will improve your speed because most third party scripts are not needed for showing any content (if they are, then they are on the critical path and you should not delay them). In addition, note that some codes make use of document.write and other methods, which do not support delaying (delaying will work as usual, but the script will not do anything or stop working).</p>
|
231 |
+
<p>If you have render blocking third party scripts, ask your provider if they can provide you with an async or defer implementation (else remove them, because render blocking scripts are not recommended for speed).</p>
|
|
|
|
|
|
|
232 |
<p><strong>Example Settings:</strong></p>
|
233 |
<p class="fvm-code-full">
|
234 |
function(w,d,s,l,i)<br>
|
242 |
<h3>Remove JavaScript Scripts</h3>
|
243 |
<div>
|
244 |
<p><strong>Notes:</strong></p>
|
245 |
+
<p>This can be used when you want to remove a duplicate JS file from the frontend source. However, if this is for a third party script you added to the header or footer (either code or via some plugin), it's better if you delete it at the source.</p>
|
|
|
|
|
246 |
</div>
|
247 |
</div>
|
248 |
|
274 |
<h3>CDN URL</h3>
|
275 |
<div>
|
276 |
<p><strong>Notes:</strong></p>
|
277 |
+
<p>This is not required for providers such as Cloudflare.com as well as any reverse proxy CDN service that doesn't change your domain name (the whole site goes through their service).</p>
|
278 |
+
<p>For other types of CDN, you are usually provided with an alternative domain name from where your static files can be served and in those cases, you would introduce your new domain name here.</p>
|
279 |
</div>
|
280 |
<h3>CDN Integration</h3>
|
281 |
<div>
|
282 |
<p><strong>Notes:</strong></p>
|
283 |
+
<p>Uses syntax from <a target="_blank" href="https://simplehtmldom.sourceforge.io/manual.htm">https://simplehtmldom.sourceforge.io/manual.htm</a> for modifying the HTML.</p>
|
284 |
+
<p>The plugin will replace your site domain url with the CDN domain for the matching HTML tags.</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
285 |
</div>
|
286 |
</div>
|
287 |
|
342 |
<div>
|
343 |
<p><strong>Notes:</strong></p>
|
344 |
<p>Simply disable the plugin, and make sure to purge all page caches (Cache Plugins, Hosting, OPCache, etc).</p>
|
345 |
+
<p>Note that some hosts rate limit the amount of times you can purge caches to once every few minutes, so you may be purging and it doesn't work, because you are being rate limited by your hosting cache system. If that happens, just wait and try again later or ask your hosting to manually purge all caches on the server.</p>
|
346 |
+
<p>You can also delete any database entries on the wp_options table starting with fastvelocity to completely purge it.</p>
|
347 |
<p>FVM does not modify your site. It runs after your template loads and filters the final HTML to present it to your users, in a more optimized way.</p>
|
348 |
</div>
|
349 |
<h3>I have disabled FVM but somehow the cache files are still being generated?</h3>
|
350 |
<div>
|
351 |
<p><strong>Notes:</strong></p>
|
352 |
+
<p>If you already purged all caches available, please ensure you have deleted the plugin and that it's no longer visible via wp-admin. If you still see references to FVM in incognito mode via google chrome, that means your server still has full page cache in memory that needs to be cleared.</p>
|
353 |
+
<p>A few hosting providers will put your files on a remote storage and cache your disk and files in memory to speed things up, which may cause code to be cached even if you have completely deleted it from the remote storage. This means, it may take a few minutes, or several hours for the actual code to update. In that case, restart the server or ask your hosting to purge all disk and page caching memory.</p>
|
|
|
354 |
</div>
|
355 |
<h3>Where can I get support or ask questions about the plugin?</h3>
|
356 |
<div>
|
360 |
<h3>How is it possible that some scan is showing malware on the plugin?</h3>
|
361 |
<div>
|
362 |
<p><strong>Notes:</strong></p>
|
363 |
+
<p>I guarantee that the plugin is 100% clean of malware, provided you have downloaded the plugin from the official WordPress source AND that your other plugins, theme or core is not compromised.</p>
|
364 |
+
<p>Malware can infect any plugin (even security plugins) regardless of the point of entry. Sometimes it propagates from different areas (including other sites you may have on the same server) or through a vulnerability on another theme or plugin (even disabled plugins or themes sometimes). </p>
|
365 |
+
<p>For that reason, if there is already malware on any JS files or CSS being merged by FVM, they would still be merged as they are, as FVM also reads them as they are. </p>
|
366 |
+
<p>If you are seeing malware on any cache file related to FVM, simply purge all caches and delete the FVM plugin. Then hire someone to manually audit the site (plugins or automated malware checks are not 100% accurate). You can then reinstall the FVM plugin from the official source on wordpress.org or via wp-admin if you like.</p>
|
367 |
</div>
|
368 |
<h3>How do I report a security issue or file a bug report?</h3>
|
369 |
<div>
|
layout/admin-layout-settings.php
CHANGED
@@ -17,32 +17,12 @@
|
|
17 |
<tr>
|
18 |
<th scope="row"><?php _e( 'Global Options', 'fast-velocity-minify' ); ?></th>
|
19 |
<td>
|
20 |
-
<p class="fvm-bold-green fvm-rowintro"><?php _e( 'Recommended Settings', 'fast-velocity-minify' ); ?></p>
|
21 |
-
|
22 |
-
<fieldset>
|
23 |
-
|
24 |
-
<label for="fvm_settings_global_preserve_settings">
|
25 |
-
<input name="fvm_settings[global][preserve_settings]" type="checkbox" id="fvm_settings_global_preserve_settings" value="1" <?php echo fvm_get_settings_checkbox(fvm_get_settings_value($fvm_settings, 'global', 'preserve_settings')); ?>>
|
26 |
-
<?php _e( 'Preserve settings on uninstall', 'fast-velocity-minify' ); ?> <span class="note-info">[ <?php _e( 'If selected, all FVM settings will be preserved when you uninstall or delete the plugin.', 'fast-velocity-minify' ); ?> ]</span></label>
|
27 |
-
<br />
|
28 |
-
|
29 |
-
<label for="fvm_settings_global_force-ssl">
|
30 |
-
<input name="fvm_settings[global][force-ssl]" type="checkbox" id="fvm_settings_global_force-ssl" value="1" <?php echo fvm_get_settings_checkbox(fvm_get_settings_value($fvm_settings, 'global', 'force-ssl')); ?>>
|
31 |
-
<?php _e( 'Force HTTPS urls on merged files', 'fast-velocity-minify' ); ?> <span class="note-info">[ <?php _e( 'Recommended if you have SSL but still allow http access to the site.', 'fast-velocity-minify' ); ?> ]</span></label>
|
32 |
-
<br />
|
33 |
-
|
34 |
-
</fieldset></td>
|
35 |
-
</tr>
|
36 |
-
|
37 |
-
<tr>
|
38 |
-
<th scope="row"><?php _e( 'Advanced Global Options', 'fast-velocity-minify' ); ?></th>
|
39 |
-
<td>
|
40 |
<p class="fvm-bold-green fvm-rowintro"><?php _e( 'Handle with Care', 'fast-velocity-minify' ); ?></p>
|
41 |
|
42 |
<fieldset>
|
43 |
<label for="fvm_settings_cache_min_instant_purge">
|
44 |
<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')); ?>>
|
45 |
-
<?php _e( 'Purge Minified CSS/JS files instantly', 'fast-velocity-minify' ); ?> <span class="note-info">[ <?php _e( 'Cache files
|
46 |
<br />
|
47 |
|
48 |
</fieldset></td>
|
@@ -95,7 +75,7 @@
|
|
95 |
<fieldset>
|
96 |
<label for="fvm_settings_html_min_disable">
|
97 |
<input name="fvm_settings[html][min_disable]" type="checkbox" id="fvm_settings_html_min_disable" value="1" <?php echo fvm_get_settings_checkbox(fvm_get_settings_value($fvm_settings, 'html', 'min_disable')); ?>>
|
98 |
-
<?php _e( 'Disable HTML Minification', 'fast-velocity-minify' ); ?> <span class="note-info">[ <?php _e( 'Will disable HTML minification for
|
99 |
<br />
|
100 |
|
101 |
</fieldset></td>
|
@@ -142,24 +122,24 @@
|
|
142 |
|
143 |
<fieldset>
|
144 |
|
145 |
-
<label for="
|
146 |
-
<input name="fvm_settings[css][
|
147 |
-
<?php _e( '
|
148 |
<br />
|
149 |
|
150 |
<label for="fvm_settings_css_min_disable">
|
151 |
<input name="fvm_settings[css][min_disable]" type="checkbox" id="fvm_settings_css_min_disable" value="1" <?php echo fvm_get_settings_checkbox(fvm_get_settings_value($fvm_settings, 'css', 'min_disable')); ?>>
|
152 |
-
<?php _e( 'Disable CSS Minification', 'fast-velocity-minify' ); ?> <span class="note-info">[ <?php _e( 'Will
|
153 |
<br />
|
154 |
|
155 |
-
<label for="
|
156 |
-
<input name="fvm_settings[css][
|
157 |
-
<?php _e( 'Disable CSS
|
158 |
<br />
|
159 |
|
160 |
-
<label for="
|
161 |
-
<input name="fvm_settings[css][
|
162 |
-
<?php _e( '
|
163 |
<br />
|
164 |
|
165 |
</fieldset></td>
|
@@ -185,6 +165,16 @@
|
|
185 |
</fieldset></td>
|
186 |
</tr>
|
187 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
188 |
|
189 |
</tbody>
|
190 |
</table>
|
@@ -193,7 +183,7 @@
|
|
193 |
|
194 |
<div style="height: 60px;"></div>
|
195 |
<h2 class="title"><?php _e( 'JS Settings', 'fast-velocity-minify' ); ?></h2>
|
196 |
-
<h3 class="fvm-bold-green"><?php _e( 'In this section, you can optimize your JS files and inline scripts', 'fast-velocity-minify' ); ?></h3>
|
197 |
|
198 |
<table class="form-table fvm-settings">
|
199 |
<tbody>
|
@@ -218,19 +208,26 @@
|
|
218 |
<p class="fvm-bold-green fvm-rowintro"><?php _e( 'Handle with Care', 'fast-velocity-minify' ); ?></p>
|
219 |
|
220 |
<fieldset>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
221 |
<label for="fvm_settings_js_min_disable">
|
222 |
<input name="fvm_settings[js][min_disable]" type="checkbox" id="fvm_settings_js_min_disable" value="1" <?php echo fvm_get_settings_checkbox(fvm_get_settings_value($fvm_settings, 'js', 'min_disable')); ?>>
|
223 |
-
<?php _e( 'Disable JS Minification', 'fast-velocity-minify' ); ?> <span class="note-info">[ <?php _e( 'Will disable JS minification
|
224 |
<br />
|
225 |
|
226 |
-
<label for="
|
227 |
-
<input name="fvm_settings[js][
|
228 |
-
<?php _e( 'Disable JS
|
229 |
<br />
|
230 |
|
231 |
-
<label for="
|
232 |
-
<input name="fvm_settings[js][
|
233 |
-
<?php _e( '
|
234 |
<br />
|
235 |
|
236 |
</fieldset></td>
|
@@ -240,7 +237,7 @@
|
|
240 |
<tr>
|
241 |
<th scope="row"><?php _e( 'Ignore Script Files', 'fast-velocity-minify' ); ?></th>
|
242 |
<td><fieldset>
|
243 |
-
<label for="fvm_settings_js_ignore"><span class="fvm-bold-green fvm-rowintro"><?php _e( 'Will prevent merging
|
244 |
<p><textarea name="fvm_settings[js][ignore]" rows="7" cols="50" id="fvm_settings_js_ignore" class="large-text code" placeholder="<?php _e( '--- ex: /plugins/something/assets/problem.js ---', 'fast-velocity-minify' ); ?>"><?php echo fvm_get_settings_value($fvm_settings, 'js', 'ignore'); ?></textarea></p>
|
245 |
<p class="description">[ <?php _e( 'Will match using <code>PHP stripos</code> against the script <code>src</code> attribute', 'fast-velocity-minify' ); ?> ]</p>
|
246 |
<p class="description">[ <?php _e( 'It is highly recommended to try to leave this empty and later be more specific on what to merge', 'fast-velocity-minify' ); ?> ]</p>
|
@@ -248,55 +245,55 @@
|
|
248 |
</tr>
|
249 |
|
250 |
<tr>
|
251 |
-
<th scope="row"><?php _e( '
|
252 |
<td><fieldset>
|
253 |
-
<label for="fvm_settings_merge_header"><span class="fvm-bold-green fvm-rowintro"><?php _e( 'This will
|
254 |
-
<p><textarea name="fvm_settings[js][merge_header]" rows="7" cols="50" id="fvm_settings_js_merge_header" class="large-text code" placeholder="<?php _e( '---
|
255 |
-
|
256 |
/jquery-migrate.js
|
257 |
/jquery.js
|
258 |
/jquery.min.js"><?php echo fvm_get_settings_value($fvm_settings, 'js', 'merge_header'); ?></textarea></p>
|
259 |
-
<p class="description">[ <?php _e( 'One possible match per line, after minification and processing, as seen on the frontend.', 'fast-velocity-minify' ); ?> ]</p>
|
260 |
<p class="description">[ <?php _e( 'Will match using <code>PHP stripos</code> against the script <code>src attribute</code>', 'fast-velocity-minify' ); ?> ]</p>
|
261 |
</fieldset></td>
|
262 |
</tr>
|
263 |
|
264 |
<tr>
|
265 |
-
<th scope="row"><?php _e( '
|
266 |
<td><fieldset>
|
267 |
-
<label for="fvm_settings_merge_defer"><span class="fvm-bold-green fvm-rowintro"><?php _e( 'This will
|
268 |
-
<p><textarea name="fvm_settings[js][merge_defer]" rows="7" cols="50" id="fvm_settings_js_merge_defer" class="large-text code" placeholder="<?php _e( '--- example ---', 'fast-velocity-minify' ); ?>
|
269 |
-
|
270 |
/wp-admin/
|
271 |
/wp-includes/
|
272 |
/wp-content/"><?php echo fvm_get_settings_value($fvm_settings, 'js', 'merge_defer'); ?></textarea></p>
|
273 |
-
<p class="description">[ <?php _e( 'One possible match per line, after minification and processing, as seen on the frontend.', 'fast-velocity-minify' ); ?> ]</p>
|
274 |
<p class="description">[ <?php _e( 'Will match using <code>PHP stripos</code> against the script <code>src attribute', 'fast-velocity-minify' ); ?></code> ]</p>
|
275 |
</fieldset></td>
|
276 |
</tr>
|
277 |
|
278 |
<tr>
|
279 |
-
<th scope="row"><?php _e( 'Inline JavaScript
|
280 |
<td><fieldset>
|
281 |
-
<label for="fvm_settings_defer_dependencies"><span class="fvm-bold-green fvm-rowintro"><?php _e( '
|
282 |
-
<p><textarea name="fvm_settings[js][defer_dependencies]" rows="7" cols="50" id="fvm_settings_js_defer_dependencies" class="large-text code" placeholder="<?php _e( '---
|
283 |
-
|
|
|
|
|
|
|
|
|
|
|
284 |
<p class="description">[ <?php _e( 'Will match using <code>PHP stripos</code> against the script <code>innerHTML</code>', 'fast-velocity-minify' ); ?> ]</p>
|
285 |
</fieldset></td>
|
286 |
</tr>
|
287 |
|
288 |
<tr>
|
289 |
-
<th scope="row"><?php _e( '
|
290 |
<td><fieldset>
|
291 |
-
<label for="fvm_settings_js_thirdparty"><span class="fvm-bold-green fvm-rowintro"><?php _e( 'Delay
|
292 |
<p><textarea name="fvm_settings[js][thirdparty]" rows="7" cols="50" id="fvm_settings_js_thirdparty" class="large-text code" placeholder="<?php _e( '--- example ---', 'fast-velocity-minify' ); ?>
|
293 |
-
|
294 |
function(w,d,s,l,i)
|
295 |
function(f,b,e,v,n,t,s)
|
296 |
function(h,o,t,j,a,r)
|
297 |
www.googletagmanager.com/gtm.js"><?php echo fvm_get_settings_value($fvm_settings, 'js', 'thirdparty'); ?></textarea></p>
|
298 |
-
<p class="description">[ <?php _e( '
|
299 |
-
<p class="description">[ <?php _e( 'Will match using <code>PHP stripos</code> against the script <code>innerHTML</code> or <code>src</code> attribute for
|
300 |
</fieldset></td>
|
301 |
</tr>
|
302 |
|
@@ -304,7 +301,8 @@ www.googletagmanager.com/gtm.js"><?php echo fvm_get_settings_value($fvm_settings
|
|
304 |
<th scope="row"><?php _e( 'Remove JavaScript Scripts', 'fast-velocity-minify' ); ?></th>
|
305 |
<td><fieldset>
|
306 |
<label for="fvm_settings_js_remove"><span class="fvm-bold-green fvm-rowintro"><?php _e( 'Remove the following JS files or Inline Scripts', 'fast-velocity-minify' ); ?></span></label>
|
307 |
-
<p><textarea name="fvm_settings[js][remove]" rows="7" cols="50" id="fvm_settings_js_remove" class="large-text code" placeholder="
|
|
|
308 |
<p class="description">[ <?php _e( 'This will allow you to remove unwanted script tags from the frontend', 'fast-velocity-minify' ); ?> ]</p>
|
309 |
<p class="description">[ <?php _e( 'Will match using <code>PHP stripos</code> against the script <code>outerHTML</code>', 'fast-velocity-minify' ); ?> ]</p>
|
310 |
</fieldset></td>
|
@@ -349,7 +347,7 @@ www.googletagmanager.com/gtm.js"><?php echo fvm_get_settings_value($fvm_settings
|
|
349 |
<td><fieldset>
|
350 |
<label for="fvm_settings_cdn_domain">
|
351 |
<p><input type="text" name="fvm_settings[cdn][domain]" id="fvm_settings_cdn_domain" value="<?php echo fvm_get_settings_value($fvm_settings, 'cdn', 'domain'); ?>" size="80" /></p>
|
352 |
-
<p class="description">[ <?php _e( '
|
353 |
</label>
|
354 |
<br />
|
355 |
</fieldset></td>
|
@@ -357,39 +355,9 @@ www.googletagmanager.com/gtm.js"><?php echo fvm_get_settings_value($fvm_settings
|
|
357 |
<tr>
|
358 |
<th scope="row"><?php _e( 'CDN Integration', 'fast-velocity-minify' ); ?></th>
|
359 |
<td><fieldset>
|
360 |
-
<label for="fvm_settings_cdn_integration"><span class="fvm-bold-green fvm-rowintro"><?php _e( '
|
361 |
<p><textarea name="fvm_settings[cdn][integration]" rows="7" cols="50" id="fvm_settings_cdn_integration" class="large-text code" placeholder="--- check the help section for suggestions ---"><?php echo fvm_get_settings_value($fvm_settings, 'cdn', 'integration'); ?></textarea></p>
|
362 |
-
<p class="description">[ <?php _e( '
|
363 |
-
<p class="description">[ <?php _e( 'You can target a child of a specific html tag, an element with a specific attribute, class or id.', 'fast-velocity-minify' ); ?> ]</p>
|
364 |
-
</fieldset></td>
|
365 |
-
</tr>
|
366 |
-
</tbody></table>
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
<div style="height: 60px;"></div>
|
371 |
-
<h2 class="title"><?php _e( 'Cache Location', 'fast-velocity-minify' ); ?></h2>
|
372 |
-
<h3 class="fvm-bold-green"><?php _e( 'FVM does not have page caching, so these settings are for the generated CSS and JS files only', 'fast-velocity-minify' ); ?></h3>
|
373 |
-
<table class="form-table fvm-settings">
|
374 |
-
<tbody>
|
375 |
-
<tr>
|
376 |
-
<th scope="row"><span class="fvm-label-special"><?php _e( 'Public Files Cache Path', 'fast-velocity-minify' ); ?></span></th>
|
377 |
-
<td><fieldset>
|
378 |
-
<label for="fvm_settings_cache_path">
|
379 |
-
<p><input type="text" name="fvm_settings[cache][path]" id="fvm_settings_cache_path" value="<?php echo fvm_get_settings_value($fvm_settings, 'cache', 'path'); ?>" size="80" /></p>
|
380 |
-
<p class="description">[ <?php _e( 'Current base path:', 'fast-velocity-minify' ); ?> <code><?php echo $fvm_cache_paths['cache_base_dir']; ?></code> ]</p>
|
381 |
-
</label>
|
382 |
-
<br />
|
383 |
-
</fieldset></td>
|
384 |
-
</tr>
|
385 |
-
<tr>
|
386 |
-
<th scope="row"><span class="fvm-label-special"><?php _e( 'Public Files Cache URL', 'fast-velocity-minify' ); ?></span></th>
|
387 |
-
<td><fieldset>
|
388 |
-
<label for="fvm_settings_cache_url">
|
389 |
-
<p><input type="text" name="fvm_settings[cache][url]" id="fvm_settings_cache_url" value="<?php echo fvm_get_settings_value($fvm_settings, 'cache', 'url'); ?>" size="80" /></p>
|
390 |
-
<p class="description">[ <?php _e( 'Current base url:', 'fast-velocity-minify' ); ?> <code><?php echo $fvm_cache_paths['cache_base_dirurl']; ?></code> ]</p>
|
391 |
-
</label>
|
392 |
-
<br />
|
393 |
</fieldset></td>
|
394 |
</tr>
|
395 |
</tbody></table>
|
17 |
<tr>
|
18 |
<th scope="row"><?php _e( 'Global Options', 'fast-velocity-minify' ); ?></th>
|
19 |
<td>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
20 |
<p class="fvm-bold-green fvm-rowintro"><?php _e( 'Handle with Care', 'fast-velocity-minify' ); ?></p>
|
21 |
|
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( 'Cache files are only deleted if older than 24h by default, for compatibility with certain hosting providers.', 'fast-velocity-minify' ); ?> ]</span></label>
|
26 |
<br />
|
27 |
|
28 |
</fieldset></td>
|
75 |
<fieldset>
|
76 |
<label for="fvm_settings_html_min_disable">
|
77 |
<input name="fvm_settings[html][min_disable]" type="checkbox" id="fvm_settings_html_min_disable" value="1" <?php echo fvm_get_settings_checkbox(fvm_get_settings_value($fvm_settings, 'html', 'min_disable')); ?>>
|
78 |
+
<?php _e( 'Disable HTML Minification', 'fast-velocity-minify' ); ?> <span class="note-info">[ <?php _e( 'Will disable HTML minification for compatibility purposes', 'fast-velocity-minify' ); ?> ]</span></label>
|
79 |
<br />
|
80 |
|
81 |
</fieldset></td>
|
122 |
|
123 |
<fieldset>
|
124 |
|
125 |
+
<label for="fvm_settings_css_nopreload">
|
126 |
+
<input name="fvm_settings[css][combine]" type="checkbox" id="fvm_settings_css_combine" value="1" <?php echo fvm_get_settings_checkbox(fvm_get_settings_value($fvm_settings, 'css', 'combine')); ?>>
|
127 |
+
<?php _e( 'Combine CSS Files', 'fast-velocity-minify' ); ?> <span class="note-info">[ <?php _e( 'Deprecated: Will combine all CSS files by mediatype groups in the header (no longer recommended for HTTP/2 servers)', 'fast-velocity-minify' ); ?> ]</span></label>
|
128 |
<br />
|
129 |
|
130 |
<label for="fvm_settings_css_min_disable">
|
131 |
<input name="fvm_settings[css][min_disable]" type="checkbox" id="fvm_settings_css_min_disable" value="1" <?php echo fvm_get_settings_checkbox(fvm_get_settings_value($fvm_settings, 'css', 'min_disable')); ?>>
|
132 |
+
<?php _e( 'Disable CSS Files Minification', 'fast-velocity-minify' ); ?> <span class="note-info">[ <?php _e( 'Will disable CSS Files minification for compatibility purposes', 'fast-velocity-minify' ); ?> ]</span></label>
|
133 |
<br />
|
134 |
|
135 |
+
<label for="fvm_settings_css_min_disable">
|
136 |
+
<input name="fvm_settings[css][min_disable_styles]" type="checkbox" id="fvm_settings_css_min_disable_styles" value="1" <?php echo fvm_get_settings_checkbox(fvm_get_settings_value($fvm_settings, 'css', 'min_disable_styles')); ?>>
|
137 |
+
<?php _e( 'Disable CSS Styles Minification', 'fast-velocity-minify' ); ?> <span class="note-info">[ <?php _e( 'Will disable CSS Styles minification for compatibility purposes', 'fast-velocity-minify' ); ?> ]</span></label>
|
138 |
<br />
|
139 |
|
140 |
+
<label for="fvm_settings_css_nopreload">
|
141 |
+
<input name="fvm_settings[css][nopreload]" type="checkbox" id="fvm_settings_css_nopreload" value="1" <?php echo fvm_get_settings_checkbox(fvm_get_settings_value($fvm_settings, 'css', 'nopreload')); ?>>
|
142 |
+
<?php _e( 'Disable CSS Link Preload', 'fast-velocity-minify' ); ?> <span class="note-info">[ <?php _e( 'Will remove the Render Blocking CSS files Link Preload from the header', 'fast-velocity-minify' ); ?> ]</span></label>
|
143 |
<br />
|
144 |
|
145 |
</fieldset></td>
|
165 |
</fieldset></td>
|
166 |
</tr>
|
167 |
|
168 |
+
<tr>
|
169 |
+
<th scope="row"><?php _e( 'Async CSS Files', 'fast-velocity-minify' ); ?></th>
|
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 remove unwanted CSS files by URL 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>
|
177 |
+
|
178 |
|
179 |
</tbody>
|
180 |
</table>
|
183 |
|
184 |
<div style="height: 60px;"></div>
|
185 |
<h2 class="title"><?php _e( 'JS Settings', 'fast-velocity-minify' ); ?></h2>
|
186 |
+
<h3 class="fvm-bold-green"><?php _e( 'In this section, you can optimize your JS files and inline scripts manually (by default all scripts are ignored for compatibility reasons).', 'fast-velocity-minify' ); ?></h3>
|
187 |
|
188 |
<table class="form-table fvm-settings">
|
189 |
<tbody>
|
208 |
<p class="fvm-bold-green fvm-rowintro"><?php _e( 'Handle with Care', 'fast-velocity-minify' ); ?></p>
|
209 |
|
210 |
<fieldset>
|
211 |
+
|
212 |
+
<label for="fvm_settings_js_combine">
|
213 |
+
<input name="fvm_settings[js][combine]" type="checkbox" id="fvm_settings_js_combine" value="1" <?php echo fvm_get_settings_checkbox(fvm_get_settings_value($fvm_settings, 'js', 'combine')); ?>>
|
214 |
+
<?php _e( 'Combine JS Files', 'fast-velocity-minify' ); ?> <span class="note-info">[<?php _e( 'Deprecated: Will combine all JS files by render blocking type (no longer recommended for HTTP/2 servers)', 'fast-velocity-minify' ); ?> ]</span></label>
|
215 |
+
<br />
|
216 |
+
|
217 |
+
|
218 |
<label for="fvm_settings_js_min_disable">
|
219 |
<input name="fvm_settings[js][min_disable]" type="checkbox" id="fvm_settings_js_min_disable" value="1" <?php echo fvm_get_settings_checkbox(fvm_get_settings_value($fvm_settings, 'js', 'min_disable')); ?>>
|
220 |
+
<?php _e( 'Disable JS Files Minification', 'fast-velocity-minify' ); ?> <span class="note-info">[ <?php _e( 'Will disable JS Files minification for testing purposes', 'fast-velocity-minify' ); ?> ]</span></label>
|
221 |
<br />
|
222 |
|
223 |
+
<label for="fvm_settings_js_min_disable_inline">
|
224 |
+
<input name="fvm_settings[js][min_disable_inline]" type="checkbox" id="fvm_settings_js_min_disable_inline" value="1" <?php echo fvm_get_settings_checkbox(fvm_get_settings_value($fvm_settings, 'js', 'min_disable_inline')); ?>>
|
225 |
+
<?php _e( 'Disable JS Inline Minification', 'fast-velocity-minify' ); ?> <span class="note-info">[ <?php _e( 'Will disable JS Inline minification for testing purposes', 'fast-velocity-minify' ); ?> ]</span></label>
|
226 |
<br />
|
227 |
|
228 |
+
<label for="fvm_settings_js_inline-all">
|
229 |
+
<input name="fvm_settings[js][nopreload]" type="checkbox" id="fvm_settings_js_nopreload" value="1" <?php echo fvm_get_settings_checkbox(fvm_get_settings_value($fvm_settings, 'js', 'nopreload')); ?>>
|
230 |
+
<?php _e( 'Disable JS link Preload', 'fast-velocity-minify' ); ?> <span class="note-info">[ <?php _e( 'Will remove the Render Blocking JS files Link Preload from the header', 'fast-velocity-minify' ); ?> ]</span></label>
|
231 |
<br />
|
232 |
|
233 |
</fieldset></td>
|
237 |
<tr>
|
238 |
<th scope="row"><?php _e( 'Ignore Script Files', 'fast-velocity-minify' ); ?></th>
|
239 |
<td><fieldset>
|
240 |
+
<label for="fvm_settings_js_ignore"><span class="fvm-bold-green fvm-rowintro"><?php _e( 'Will prevent merging or minification for all JS files matching the paths below', 'fast-velocity-minify' ); ?></span></label>
|
241 |
<p><textarea name="fvm_settings[js][ignore]" rows="7" cols="50" id="fvm_settings_js_ignore" class="large-text code" placeholder="<?php _e( '--- ex: /plugins/something/assets/problem.js ---', 'fast-velocity-minify' ); ?>"><?php echo fvm_get_settings_value($fvm_settings, 'js', 'ignore'); ?></textarea></p>
|
242 |
<p class="description">[ <?php _e( 'Will match using <code>PHP stripos</code> against the script <code>src</code> attribute', 'fast-velocity-minify' ); ?> ]</p>
|
243 |
<p class="description">[ <?php _e( 'It is highly recommended to try to leave this empty and later be more specific on what to merge', 'fast-velocity-minify' ); ?> ]</p>
|
245 |
</tr>
|
246 |
|
247 |
<tr>
|
248 |
+
<th scope="row"><?php _e( 'Render Blocking JS files', 'fast-velocity-minify' ); ?></th>
|
249 |
<td><fieldset>
|
250 |
+
<label for="fvm_settings_merge_header"><span class="fvm-bold-green fvm-rowintro"><?php _e( 'This will render block all JS files matching the paths below', 'fast-velocity-minify' ); ?></span></label>
|
251 |
+
<p><textarea name="fvm_settings[js][merge_header]" rows="7" cols="50" id="fvm_settings_js_merge_header" class="large-text code" placeholder="<?php _e( '--- example ---', 'fast-velocity-minify' ); ?>
|
|
|
252 |
/jquery-migrate.js
|
253 |
/jquery.js
|
254 |
/jquery.min.js"><?php echo fvm_get_settings_value($fvm_settings, 'js', 'merge_header'); ?></textarea></p>
|
|
|
255 |
<p class="description">[ <?php _e( 'Will match using <code>PHP stripos</code> against the script <code>src attribute</code>', 'fast-velocity-minify' ); ?> ]</p>
|
256 |
</fieldset></td>
|
257 |
</tr>
|
258 |
|
259 |
<tr>
|
260 |
+
<th scope="row"><?php _e( 'Defer JS Files', 'fast-velocity-minify' ); ?></th>
|
261 |
<td><fieldset>
|
262 |
+
<label for="fvm_settings_merge_defer"><span class="fvm-bold-green fvm-rowintro"><?php _e( 'This will defer all JS files matching the paths below', 'fast-velocity-minify' ); ?></span></label>
|
263 |
+
<p><textarea name="fvm_settings[js][merge_defer]" rows="7" cols="50" id="fvm_settings_js_merge_defer" class="large-text code" placeholder="<?php _e( '--- example ---', 'fast-velocity-minify' ); ?>
|
|
|
264 |
/wp-admin/
|
265 |
/wp-includes/
|
266 |
/wp-content/"><?php echo fvm_get_settings_value($fvm_settings, 'js', 'merge_defer'); ?></textarea></p>
|
|
|
267 |
<p class="description">[ <?php _e( 'Will match using <code>PHP stripos</code> against the script <code>src attribute', 'fast-velocity-minify' ); ?></code> ]</p>
|
268 |
</fieldset></td>
|
269 |
</tr>
|
270 |
|
271 |
<tr>
|
272 |
+
<th scope="row"><?php _e( 'Defer Inline JavaScript', 'fast-velocity-minify' ); ?></th>
|
273 |
<td><fieldset>
|
274 |
+
<label for="fvm_settings_defer_dependencies"><span class="fvm-bold-green fvm-rowintro"><?php _e( 'Preserve the order of scripts execution when deferring JS files dependencies', 'fast-velocity-minify' ); ?></span></label>
|
275 |
+
<p><textarea name="fvm_settings[js][defer_dependencies]" rows="7" cols="50" id="fvm_settings_js_defer_dependencies" class="large-text code" placeholder="<?php _e( '--- example ---', 'fast-velocity-minify' ); ?>
|
276 |
+
wp.i18n
|
277 |
+
wp.apiFetch.use
|
278 |
+
window.lodash
|
279 |
+
wp.hooks
|
280 |
+
wp.url"><?php echo fvm_get_settings_value($fvm_settings, 'js', 'defer_dependencies'); ?></textarea></p>
|
281 |
+
<p class="description">[ <?php _e( 'Inline JavaScript matching these rules, will be deferred with script type module', 'fast-velocity-minify' ); ?> ]</p>
|
282 |
<p class="description">[ <?php _e( 'Will match using <code>PHP stripos</code> against the script <code>innerHTML</code>', 'fast-velocity-minify' ); ?> ]</p>
|
283 |
</fieldset></td>
|
284 |
</tr>
|
285 |
|
286 |
<tr>
|
287 |
+
<th scope="row"><?php _e( 'Delay third party scripts until user interaction', 'fast-velocity-minify' ); ?></th>
|
288 |
<td><fieldset>
|
289 |
+
<label for="fvm_settings_js_thirdparty"><span class="fvm-bold-green fvm-rowintro"><?php _e( 'Delay JS files or inline scripts until user interaction', 'fast-velocity-minify' ); ?></span></label>
|
290 |
<p><textarea name="fvm_settings[js][thirdparty]" rows="7" cols="50" id="fvm_settings_js_thirdparty" class="large-text code" placeholder="<?php _e( '--- example ---', 'fast-velocity-minify' ); ?>
|
|
|
291 |
function(w,d,s,l,i)
|
292 |
function(f,b,e,v,n,t,s)
|
293 |
function(h,o,t,j,a,r)
|
294 |
www.googletagmanager.com/gtm.js"><?php echo fvm_get_settings_value($fvm_settings, 'js', 'thirdparty'); ?></textarea></p>
|
295 |
+
<p class="description">[ <?php _e( 'Used interaction events: mouseover, keydown, touchstart, touchmove and wheel', 'fast-velocity-minify' ); ?> ]</p>
|
296 |
+
<p class="description">[ <?php _e( 'Will match using <code>PHP stripos</code> against the inline script <code>innerHTML</code> or <code>src</code> attribute for JS files', 'fast-velocity-minify' ); ?> ]</p>
|
297 |
</fieldset></td>
|
298 |
</tr>
|
299 |
|
301 |
<th scope="row"><?php _e( 'Remove JavaScript Scripts', 'fast-velocity-minify' ); ?></th>
|
302 |
<td><fieldset>
|
303 |
<label for="fvm_settings_js_remove"><span class="fvm-bold-green fvm-rowintro"><?php _e( 'Remove the following JS files or Inline Scripts', 'fast-velocity-minify' ); ?></span></label>
|
304 |
+
<p><textarea name="fvm_settings[js][remove]" rows="7" cols="50" id="fvm_settings_js_remove" class="large-text code" placeholder="<?php _e( '--- example ---', 'fast-velocity-minify' ); ?>
|
305 |
+
/some/duplicate/file.js"><?php echo fvm_get_settings_value($fvm_settings, 'js', 'remove'); ?></textarea></p>
|
306 |
<p class="description">[ <?php _e( 'This will allow you to remove unwanted script tags from the frontend', 'fast-velocity-minify' ); ?> ]</p>
|
307 |
<p class="description">[ <?php _e( 'Will match using <code>PHP stripos</code> against the script <code>outerHTML</code>', 'fast-velocity-minify' ); ?> ]</p>
|
308 |
</fieldset></td>
|
347 |
<td><fieldset>
|
348 |
<label for="fvm_settings_cdn_domain">
|
349 |
<p><input type="text" name="fvm_settings[cdn][domain]" id="fvm_settings_cdn_domain" value="<?php echo fvm_get_settings_value($fvm_settings, 'cdn', 'domain'); ?>" size="80" /></p>
|
350 |
+
<p class="description">[ <?php _e( 'You can ignore this if your CDN url matches your domain name (ie: Cloudflare)', 'fast-velocity-minify' ); ?> ]</p>
|
351 |
</label>
|
352 |
<br />
|
353 |
</fieldset></td>
|
355 |
<tr>
|
356 |
<th scope="row"><?php _e( 'CDN Integration', 'fast-velocity-minify' ); ?></th>
|
357 |
<td><fieldset>
|
358 |
+
<label for="fvm_settings_cdn_integration"><span class="fvm-bold-green fvm-rowintro"><?php _e( 'Missing HTML elements to replace', 'fast-velocity-minify' ); ?></span></label>
|
359 |
<p><textarea name="fvm_settings[cdn][integration]" rows="7" cols="50" id="fvm_settings_cdn_integration" class="large-text code" placeholder="--- check the help section for suggestions ---"><?php echo fvm_get_settings_value($fvm_settings, 'cdn', 'integration'); ?></textarea></p>
|
360 |
+
<p class="description">[ <?php _e( 'Additional replacement rules with syntax from <code>https://simplehtmldom.sourceforge.io/manual.htm</code>', 'fast-velocity-minify' ); ?> ]</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
361 |
</fieldset></td>
|
362 |
</tr>
|
363 |
</tbody></table>
|
layout/admin-layout-status.php
CHANGED
@@ -6,22 +6,11 @@ if( $active_tab == 'status' ) {
|
|
6 |
<div class="fvm-wrapper">
|
7 |
|
8 |
<div id="status">
|
9 |
-
<h2 class="title"><?php _e( 'Cache Stats', 'fast-velocity-minify' ); ?></h2>
|
10 |
-
<h3 class="fvm-cache-stats fvm-bold-green"></h3>
|
11 |
-
|
12 |
|
13 |
<div style="height: 40px;"></div>
|
14 |
-
<h2 class="title"><?php _e( '
|
15 |
-
<h3 class="fvm-bold-green"><?php _e( 'In this section, you can check the latest CSS
|
16 |
-
<textarea rows="10" cols="50" class="large-text code row-log log-css" disabled></textarea>
|
17 |
-
|
18 |
-
|
19 |
-
<div style="height: 40px;"></div>
|
20 |
-
<h2 class="title"><?php _e( 'JS Logs', 'fast-velocity-minify' ); ?></h2>
|
21 |
-
<h3 class="fvm-bold-green"><?php _e( 'In this section, you can check the latest JS merging logs', 'fast-velocity-minify' ); ?></h3>
|
22 |
-
<textarea rows="10" cols="50" class="large-text code row-log log-js" disabled></textarea>
|
23 |
-
<div style="height: 20px;"></div>
|
24 |
-
|
25 |
|
26 |
<div style="height: 40px;"></div>
|
27 |
<h2 class="title"><?php _e( 'Server Info', 'fast-velocity-minify' ); ?></h2>
|
6 |
<div class="fvm-wrapper">
|
7 |
|
8 |
<div id="status">
|
|
|
|
|
|
|
9 |
|
10 |
<div style="height: 40px;"></div>
|
11 |
+
<h2 class="title"><?php _e( 'Latest Logs', 'fast-velocity-minify' ); ?></h2>
|
12 |
+
<h3 class="fvm-bold-green"><?php _e( 'In this section, you can check the latest logs for CSS and JS files', 'fast-velocity-minify' ); ?></h3>
|
13 |
+
<div class="row-log log-stats wpraiser-textarea"><textarea rows="10" cols="50" class="large-text code row-log log-css" disabled></textarea></div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
|
15 |
<div style="height: 40px;"></div>
|
16 |
<h2 class="title"><?php _e( 'Server Info', 'fast-velocity-minify' ); ?></h2>
|
libs/raisermin/minify.php
CHANGED
@@ -38,7 +38,7 @@ function fvm_raisermin_js($code){
|
|
38 |
|
39 |
# collapse consecutive line feeds into just 1
|
40 |
$code = preg_replace('/\n+/', "\n", $code);
|
41 |
-
|
42 |
# process horizontal space
|
43 |
$code = preg_replace('/([\[\]\(\)\{\}\;\<\>])(\h+)([\[\]\(\)\{\}\;\<\>])/ui', '$1 $3', $code);
|
44 |
$code = preg_replace('/([\)])(\h?)(\.)/ui', '$1$3', $code);
|
@@ -65,129 +65,48 @@ function fvm_min_remove_utf8_bom($text) {
|
|
65 |
|
66 |
|
67 |
# minify html, don't touch certain tags
|
68 |
-
function fvm_raisermin_html($html
|
69 |
|
70 |
# clone
|
71 |
$content = $html;
|
72 |
|
73 |
# get all scripts
|
74 |
-
$
|
75 |
-
preg_match_all('
|
76 |
|
77 |
-
# replace all with
|
78 |
-
if(is_array($
|
79 |
-
foreach ($
|
80 |
-
$content = str_replace($v, '<!--
|
81 |
}
|
82 |
}
|
83 |
|
84 |
-
# get all <code> sections
|
85 |
-
$allcodes = array();
|
86 |
-
preg_match_all('/\<code(.*?)\<(\s*)\/code(\s*)\>/uis', $html, $allcodes);
|
87 |
-
|
88 |
-
# replace all with a marker
|
89 |
-
if(is_array($allcodes) && isset($allcodes[0]) && count($allcodes[0]) > 0) {
|
90 |
-
foreach ($allcodes[0] as $k=>$v) {
|
91 |
-
$content = str_replace($v, '<!-- CODE '.$k.' -->', $content);
|
92 |
-
}
|
93 |
-
}
|
94 |
-
|
95 |
-
# get all <pre> sections
|
96 |
-
$allpres = array();
|
97 |
-
preg_match_all('/\<pre(.*?)\<(\s*)\/pre(\s*)\>/uis', $html, $allpres);
|
98 |
-
|
99 |
-
# replace all with a marker
|
100 |
-
if(is_array($allpres) && isset($allpres[0]) && count($allpres[0]) > 0) {
|
101 |
-
foreach ($allpres[0] as $k=>$v) {
|
102 |
-
$content = str_replace($v, '<!-- PRE '.$k.' -->', $content);
|
103 |
-
}
|
104 |
-
}
|
105 |
-
|
106 |
# remove line breaks, and colapse two or more white spaces into one
|
107 |
$content = preg_replace('/\s+/u', " ", $content);
|
108 |
|
109 |
-
#
|
110 |
-
$content = str_replace('>
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
# add linebreaks after meta tags, for readability
|
116 |
-
$allmeta = array();
|
117 |
-
preg_match_all('/\<meta(.*?)\>/uis', $html, $allmeta);
|
118 |
-
|
119 |
-
# replace all scripts and styles with a marker
|
120 |
-
if(is_array($allmeta) && isset($allmeta[0]) && count($allmeta[0]) > 0) {
|
121 |
-
foreach ($allmeta[0] as $k=>$v) {
|
122 |
-
$content = str_replace($v, PHP_EOL . $v . PHP_EOL, $content);
|
123 |
-
}
|
124 |
-
}
|
125 |
-
|
126 |
-
# add linebreaks after link tags, for readability
|
127 |
-
$alllink = array();
|
128 |
-
preg_match_all('/\<link(.*?)\>/uis', $html, $alllink);
|
129 |
-
|
130 |
-
# replace all scripts and styles with a marker
|
131 |
-
if(is_array($alllink) && isset($alllink[0]) && count($alllink[0]) > 0) {
|
132 |
-
foreach ($alllink[0] as $k=>$v) {
|
133 |
-
$content = str_replace($v, PHP_EOL . $v . PHP_EOL, $content);
|
134 |
-
}
|
135 |
-
}
|
136 |
-
|
137 |
-
# add linebreaks after style tags, for readability
|
138 |
-
$allstyles = array();
|
139 |
-
preg_match_all('/\<s(.*?)\<(\s*)\/style(\s*)\>/uis', $html, $allstyles);
|
140 |
-
|
141 |
-
# replace all scripts and styles with a marker
|
142 |
-
if(is_array($allstyles) && isset($allstyles[0]) && count($allstyles[0]) > 0) {
|
143 |
-
foreach ($allstyles[0] as $k=>$v) {
|
144 |
-
$content = str_replace($v, PHP_EOL . $v . PHP_EOL, $content);
|
145 |
-
}
|
146 |
-
}
|
147 |
-
|
148 |
-
# add linebreaks after html and head tags, for readability
|
149 |
-
$content = str_replace('<head>', PHP_EOL . '<head>' . PHP_EOL, $content);
|
150 |
-
$content = str_replace('</head>', PHP_EOL . '</head>' . PHP_EOL, $content);
|
151 |
-
$content = str_replace('<html', PHP_EOL . '<html', $content);
|
152 |
-
$content = str_replace('</html>', PHP_EOL . '</html>', $content);
|
153 |
-
|
154 |
-
}
|
155 |
-
|
156 |
-
# replace markers for scripts
|
157 |
-
if(is_array($allscripts) && isset($allscripts[0]) && count($allscripts[0]) > 0) {
|
158 |
-
foreach ($allscripts[0] as $k=>$v) {
|
159 |
-
if($xtra === true) {
|
160 |
-
$content = str_replace('<!-- SCRIPT '.$k.' -->', PHP_EOL . $v . PHP_EOL, $content);
|
161 |
-
} else {
|
162 |
-
$content = str_replace('<!-- SCRIPT '.$k.' -->', $v, $content);
|
163 |
-
}
|
164 |
-
}
|
165 |
-
}
|
166 |
|
167 |
-
#
|
168 |
-
$content =
|
|
|
|
|
|
|
169 |
|
170 |
-
# replace markers for
|
171 |
-
if(is_array($
|
172 |
-
foreach ($
|
173 |
-
|
174 |
-
$content = str_replace('<!-- CODE '.$k.' -->', PHP_EOL . $v . PHP_EOL, $content);
|
175 |
-
} else {
|
176 |
-
$content = str_replace('<!-- CODE '.$k.' -->', $v, $content);
|
177 |
-
}
|
178 |
}
|
179 |
}
|
180 |
-
|
181 |
-
#
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
$content = str_replace('<!-- PRE '.$k.' -->', PHP_EOL . $v . PHP_EOL, $content);
|
186 |
-
} else {
|
187 |
-
$content = str_replace('<!-- PRE '.$k.' -->', $v, $content);
|
188 |
-
}
|
189 |
-
}
|
190 |
-
}
|
191 |
|
192 |
# save as html, if not empty
|
193 |
if(!empty($content)) {
|
38 |
|
39 |
# collapse consecutive line feeds into just 1
|
40 |
$code = preg_replace('/\n+/', "\n", $code);
|
41 |
+
|
42 |
# process horizontal space
|
43 |
$code = preg_replace('/([\[\]\(\)\{\}\;\<\>])(\h+)([\[\]\(\)\{\}\;\<\>])/ui', '$1 $3', $code);
|
44 |
$code = preg_replace('/([\)])(\h?)(\.)/ui', '$1$3', $code);
|
65 |
|
66 |
|
67 |
# minify html, don't touch certain tags
|
68 |
+
function fvm_raisermin_html($html) {
|
69 |
|
70 |
# clone
|
71 |
$content = $html;
|
72 |
|
73 |
# get all scripts
|
74 |
+
$skp = array();
|
75 |
+
preg_match_all('/(\<script(.*?)\<(\s*)\/script(\s*)\>|\<noscript(.*?)\<(\s*)\/noscript(\s*)\>|\<code(.*?)\<(\s*)\/code(\s*)\>|\<pre(.*?)\<(\s*)\/pre(\s*)\>)/uis', $html, $skp);
|
76 |
|
77 |
+
# replace all skippable patterns with comment
|
78 |
+
if(is_array($skp) && isset($skp[0]) && count($skp[0]) > 0) {
|
79 |
+
foreach ($skp[0] as $k=>$v) {
|
80 |
+
$content = str_replace($v, '<!-- SKIP '.$k.' -->', $content);
|
81 |
}
|
82 |
}
|
83 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
84 |
# remove line breaks, and colapse two or more white spaces into one
|
85 |
$content = preg_replace('/\s+/u', " ", $content);
|
86 |
|
87 |
+
# add linebreaks after html and head tags, for readability
|
88 |
+
$content = str_replace('<head>', PHP_EOL . '<head>' . PHP_EOL, $content);
|
89 |
+
$content = str_replace('</head>', PHP_EOL . '</head>' . PHP_EOL, $content);
|
90 |
+
$content = str_replace('<html', PHP_EOL . '<html', $content);
|
91 |
+
$content = str_replace('</html>', PHP_EOL . '</html>', $content);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
92 |
|
93 |
+
# final readability adjustments
|
94 |
+
$content = str_replace('<meta ', PHP_EOL . '<meta ', $content);
|
95 |
+
$content = str_replace('<link ', PHP_EOL . '<link ', $content);
|
96 |
+
$content = str_replace('<style', PHP_EOL . '<style', $content);
|
97 |
+
$content = str_replace('<noscript', PHP_EOL . '<noscript>', $content);
|
98 |
|
99 |
+
# replace markers for scripts last
|
100 |
+
if(is_array($skp) && isset($skp[0]) && count($skp[0]) > 0) {
|
101 |
+
foreach ($skp[0] as $k=>$v) {
|
102 |
+
$content = str_replace('<!-- SKIP '.$k.' -->', PHP_EOL . $v . PHP_EOL, $content);
|
|
|
|
|
|
|
|
|
103 |
}
|
104 |
}
|
105 |
+
|
106 |
+
# no empty lines
|
107 |
+
$lines = explode(PHP_EOL, $content);
|
108 |
+
foreach($lines as $k=>$ln) { $ln = ltrim($ln); if(empty($ln)) { unset($lines[$k]); } else { $lines[$k] = $ln; } }
|
109 |
+
$content = implode(PHP_EOL, $lines);
|
|
|
|
|
|
|
|
|
|
|
|
|
110 |
|
111 |
# save as html, if not empty
|
112 |
if(!empty($content)) {
|
readme.txt
CHANGED
@@ -1,26 +1,26 @@
|
|
1 |
=== Fast Velocity Minify ===
|
2 |
Contributors: Alignak
|
3 |
Tags: PHP Minify, Lighthouse, GTmetrix, Pingdom, Pagespeed, Merging, Minification, Optimization, Speed, Performance, FVM
|
4 |
-
Requires at least: 4.
|
5 |
Requires PHP: 5.6
|
6 |
-
Stable tag: 3.1.
|
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
|
13 |
|
14 |
|
15 |
== Description ==
|
16 |
-
Speed optimization plugin for developers and advanced users.
|
17 |
|
18 |
-
Minification is done on the frontend during the first uncached request. Once the first request is processed, any other pages that require the same set of CSS and
|
19 |
|
20 |
The plugin includes options for developers and advanced users, however the default settings should work just fine for most sites.
|
21 |
Kindly read the HELP section after installing the plugin, about possible issues and how to solve them.
|
22 |
|
23 |
-
=
|
24 |
|
25 |
I can offer you aditional `custom made` optimization on top of this plugin. If you would like to hire me, please visit my profile links for further information.
|
26 |
|
@@ -55,6 +55,15 @@ Version 3.0 is a major code rewrite to improve JS and CSS merging, but it requir
|
|
55 |
|
56 |
== Changelog ==
|
57 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
58 |
= 3.1.4 [2021.01.11] =
|
59 |
* disable FVM update routines when a user runs wp-cli commands outside of the root directory
|
60 |
* database routine improvements for users with custom table prefixes
|
1 |
=== Fast Velocity Minify ===
|
2 |
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.1.5
|
7 |
+
Tested up to: 5.7.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 your CSS and JS files (defer, async, minify, combine, etc), compressing HTML, simplifying fonts and a few more speed optimization options.
|
13 |
|
14 |
|
15 |
== Description ==
|
16 |
+
Speed optimization plugin for developers and advanced users.
|
17 |
|
18 |
+
Minification is done on the frontend during the first uncached request. Once the first request is processed, any other pages that require the same set of CSS and JS files, will be able to reuse the same generated file.
|
19 |
|
20 |
The plugin includes options for developers and advanced users, however the default settings should work just fine for most sites.
|
21 |
Kindly read the HELP section after installing the plugin, about possible issues and how to solve them.
|
22 |
|
23 |
+
= Additional Optimization =
|
24 |
|
25 |
I can offer you aditional `custom made` optimization on top of this plugin. If you would like to hire me, please visit my profile links for further information.
|
26 |
|
55 |
|
56 |
== Changelog ==
|
57 |
|
58 |
+
= 3.1.5 [2021.04.24] =
|
59 |
+
* added support for WP Cloudflare Super Page Cache plugin
|
60 |
+
* fixed support for LiteSpeed Cache purging
|
61 |
+
* changed the cache directory to the uploads directory (WP_Filesystem_Direct)
|
62 |
+
* deprecated CSS and JS merging as this is no longer recommended for HTTP/2 servers
|
63 |
+
* stop removing RSS feeds references on the header cleanup option
|
64 |
+
* changed some descriptions and updated the HELP section
|
65 |
+
* other bug fixes
|
66 |
+
|
67 |
= 3.1.4 [2021.01.11] =
|
68 |
* disable FVM update routines when a user runs wp-cli commands outside of the root directory
|
69 |
* database routine improvements for users with custom table prefixes
|