OMGF | GDPR/DSVGO Compliant, Faster Google Fonts. Easy. - Version 4.2.0

Version Description

| The What-4.0-should've-been Edition | October 7th, 2020 = * IMPORTANT NOTICE: If you're upgrading from v4.x.x it's required to Empty your Cache Directory. Otherwise the Optimized Google Fonts Overview will not work. * Added CSS2 (Variable Fonts) compatiblity, * No more spaces in filenames of downloaded fonts, * Added Optimize Fonts tab, which resembles the 'Generate Stylesheet' tab from v3, and features, * Optimization Mode: Manual or Automatic, * If Manual is selected, the URL can be specified which should be scanned for Google Fonts, * A complete overview of all detected fonts, grouped by stylesheet, * Options to preload or unload for each font. * Move settings to more sensible places and re-grouped them in 3 groups: * Optimize Fonts, * Detection Settings, * Advanced Settings. * OMGF will now throw a notice when a settings is changed which requires the cache to be flushed. * Several tweaks and fixes in OMGF's Auto Detection mechanism and Fonts Download API. * Fixed issue where OMGF wouldn't detect fonts in weight 400 (and 400 italic). * Major UX improvements, * Pros and Cons of each Optimization Mode are outlined upon selection, * Show loaded while actions are taking place, * Cleaned up sidebar and added a clear overview of available documentation. * Several tweaks and optimizations in overall performance.

Download this release

Release Info

Developer DaanvandenBergh
Plugin Icon 128x128 OMGF | GDPR/DSVGO Compliant, Faster Google Fonts. Easy.
Version 4.2.0
Comparing to
See all releases

Code changes from version 4.1.3 to 4.2.0

assets/css/omgf-admin.css CHANGED
@@ -55,6 +55,71 @@
55
  float: right;
56
  width: 21.75%;
57
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
  /**
59
  * Welcome block
60
  */
55
  float: right;
56
  width: 21.75%;
57
  }
58
+ .omgf-optimize-fonts-container {
59
+ text-align: center;
60
+ padding: 25px 50px;
61
+ }
62
+ .omgf-optimize-fonts-container h3 {
63
+ font-size: 1.3em;
64
+ margin-top: 0;
65
+ }
66
+ .omgf-optimize-fonts-container .omgf-optimize-fonts-manage {
67
+ text-align: left;
68
+ }
69
+ .omgf-optimize-fonts-container .omgf-optimize-fonts-manage table {
70
+ width: 100%;
71
+ border-collapse: collapse;
72
+ }
73
+ .omgf-optimize-fonts-container .omgf-optimize-fonts-manage table thead th {
74
+ width: 100px;
75
+ }
76
+ .omgf-optimize-fonts-container .omgf-optimize-fonts-manage table tbody {
77
+ border: 1px solid #ccd0d4;
78
+ }
79
+ .omgf-optimize-fonts-container .omgf-optimize-fonts-manage table tbody th {
80
+ padding: 5px 0 0 10px;
81
+ width: 40%;
82
+ }
83
+ .omgf-optimize-fonts-container .omgf-optimize-fonts-manage table tbody th .handle {
84
+ font-weight: 400;
85
+ }
86
+ .omgf-optimize-fonts-container .omgf-optimize-fonts-manage table tbody td {
87
+ padding-bottom: 5px;
88
+ width: 100px;
89
+ }
90
+ .omgf-optimize-fonts-container .omgf-optimize-fonts-manage table tbody tr:last-child td {
91
+ padding-bottom: 10px;
92
+ }
93
+ .omgf-optimize-fonts-container .omgf-optimize-fonts-description .omgf-optimize-fonts-pros {
94
+ margin-right: 10px;
95
+ }
96
+ .omgf-optimize-fonts-container .omgf-optimize-fonts-description .omgf-optimize-fonts-pros,
97
+ .omgf-optimize-fonts-container .omgf-optimize-fonts-description .omgf-optimize-fonts-cons {
98
+ text-align: left;
99
+ width: 48%;
100
+ display: inline-block;
101
+ vertical-align: top;
102
+ }
103
+ .omgf-optimize-fonts-container .omgf-optimize-fonts-description .omgf-optimize-fonts-pros span:before,
104
+ .omgf-optimize-fonts-container .omgf-optimize-fonts-description .omgf-optimize-fonts-cons span:before {
105
+ vertical-align: -4px;
106
+ }
107
+ .omgf-optimize-fonts-container .omgf-optimize-fonts-description label {
108
+ font-size: 18px;
109
+ font-weight: bold;
110
+ }
111
+ .omgf-optimize-fonts-container .omgf-optimize-fonts-description #omgf_manual_optimize_url {
112
+ font-size: 18px;
113
+ padding: 0 15px;
114
+ margin-left: 10px;
115
+ }
116
+ .omgf-optimize-fonts-container .omgf-optimize-fonts-tooltip {
117
+ padding: 0 15px 5px;
118
+ }
119
+ .omgf-optimize-fonts-container p,
120
+ .omgf-optimize-fonts-container ul {
121
+ text-align: justify;
122
+ }
123
  /**
124
  * Welcome block
125
  */
assets/css/omgf-admin.css.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["omgf-admin.less"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAkBA,KACE;EACE,WAAA;EACA,qBAAA;EACA,yBAAA;EACA,gBAAA;EACA,eAAA;EACA,kBAAA;EACA,mBAAA;EACA,4BAAA;;AAEA,KAVF,eAUG;EACC,eAAA;EACA,mBAAA;EACA,WAAA;EACA,qBAAA;;;;;AAQN;EACE,oBAAA;;AADF,SAGE;EACE,eAAA;;AAJJ,SAOE,kBAAiB;EACf,oBAAA;EACA,mBAAA;;;;;AAQF,gBAAC;EACC,WAAA;EACA,UAAA;;AAGF,gBAAC;EACC,YAAA;EACA,aAAA;;;;;AAOJ;EACE,sBAAA;;AADF,mBAGE;EACE,cAAA;EACA,eAAA;;AALJ,mBAQE,GAAG;EACD,gBAAA;;AAIA,mBADF,WACG,WAAW;EACV,cAAA;;AAdN,mBAkBE,cAAa;EACX,UAAA;;AAnBJ,mBAsBE;EACE,kBAAA;;AAvBJ,mBA0BE;EACE,cAAA;;;;;AAOJ;EACE,eAAA;EACA,0CAAA;EACA,WAAA;EACA,YAAA;EACA,MAAA;EACA,kBAAA;;AANF,aAQE;EACE,QAAA;EACA,SAAA;EACA,kBAAA;EACA,eAAe,kBAAf;EACA,WAAW,kBAAX;;;;;AAOJ,wBAA2C;EACzC;IACE,cAAA;IACA,WAAA;;EAEA,gBAAC;EACD,gBAAC;IACC,WAAA","file":"omgf-admin.css"}
1
+ {"version":3,"sources":["omgf-admin.less"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAkBA,KACE;EACE,WAAA;EACA,qBAAA;EACA,yBAAA;EACA,gBAAA;EACA,eAAA;EACA,kBAAA;EACA,mBAAA;EACA,4BAAA;;AAEA,KAVF,eAUG;EACC,eAAA;EACA,mBAAA;EACA,WAAA;EACA,qBAAA;;;;;AAQN;EACE,oBAAA;;AADF,SAGE;EACE,eAAA;;AAJJ,SAOE,kBAAiB;EACf,oBAAA;EACA,mBAAA;;;;;AAQF,gBAAC;EACC,WAAA;EACA,UAAA;;AAGF,gBAAC;EACC,YAAA;EACA,aAAA;;AAIJ;EACE,kBAAA;EACA,kBAAA;;AAFF,8BAIE;EACE,gBAAA;EACA,aAAA;;AANJ,8BASE;EACE,gBAAA;;AAVJ,8BASE,4BAGE;EACE,WAAA;EACA,yBAAA;;AAdN,8BASE,4BAGE,MAIE,MACE;EACE,YAAA;;AAlBV,8BASE,4BAGE,MAUE;EACE,yBAAA;;AAvBR,8BASE,4BAGE,MAUE,MAGE;EACE,qBAAA;EACA,UAAA;;AA3BV,8BASE,4BAGE,MAUE,MAGE,GAIE;EACE,gBAAA;;AA9BZ,8BASE,4BAGE,MAUE,MAYE;EACE,mBAAA;EACA,YAAA;;AApCV,8BASE,4BAGE,MAUE,MAiBE,GAAE,WACA;EACE,oBAAA;;AAzCZ,8BAgDE,iCACE;EACE,kBAAA;;AAlDN,8BAgDE,iCAKE;AArDJ,8BAgDE,iCAME;EACE,gBAAA;EACA,UAAA;EACA,qBAAA;EACA,mBAAA;;AA1DN,8BAgDE,iCAKE,0BAOE,KAAI;AA5DV,8BAgDE,iCAME,0BAME,KAAI;EACF,oBAAA;;AA7DR,8BAgDE,iCAiBE;EACE,eAAA;EACA,iBAAA;;AAnEN,8BAgDE,iCAsBE;EACE,eAAA;EACA,eAAA;EACA,iBAAA;;AAzEN,8BA6EE;EACE,mBAAA;;AA9EJ,8BAiFE;AAjFF,8BAkFE;EACE,mBAAA;;;;;AAOJ;EACE,sBAAA;;AADF,mBAGE;EACE,cAAA;EACA,eAAA;;AALJ,mBAQE,GAAG;EACD,gBAAA;;AAIA,mBADF,WACG,WAAW;EACV,cAAA;;AAdN,mBAkBE,cAAa;EACX,UAAA;;AAnBJ,mBAsBE;EACE,kBAAA;;AAvBJ,mBA0BE;EACE,cAAA;;;;;AAOJ;EACE,eAAA;EACA,0CAAA;EACA,WAAA;EACA,YAAA;EACA,MAAA;EACA,kBAAA;;AANF,aAQE;EACE,QAAA;EACA,SAAA;EACA,kBAAA;EACA,eAAe,kBAAf;EACA,WAAW,kBAAX;;;;;AAOJ,wBAA2C;EACzC;IACE,cAAA;IACA,WAAA;;EAEA,gBAAC;EACD,gBAAC;IACC,WAAA","file":"omgf-admin.css"}
assets/css/omgf-admin.less CHANGED
@@ -67,6 +67,93 @@
67
  }
68
  }
69
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
  /**
71
  * Welcome block
72
  */
67
  }
68
  }
69
 
70
+ .omgf-optimize-fonts-container {
71
+ text-align: center;
72
+ padding: 25px 50px;
73
+
74
+ h3 {
75
+ font-size: 1.3em;
76
+ margin-top: 0;
77
+ }
78
+
79
+ .omgf-optimize-fonts-manage {
80
+ text-align: left;
81
+
82
+ table {
83
+ width: 100%;
84
+ border-collapse: collapse;
85
+
86
+ thead {
87
+ th {
88
+ width: 100px;
89
+ }
90
+ }
91
+
92
+ tbody {
93
+ border: 1px solid #ccd0d4;
94
+
95
+ th {
96
+ padding: 5px 0 0 10px;
97
+ width: 40%;
98
+
99
+ .handle {
100
+ font-weight: 400;
101
+ }
102
+ }
103
+
104
+ td {
105
+ padding-bottom: 5px;
106
+ width: 100px;
107
+ }
108
+
109
+ tr:last-child {
110
+ td {
111
+ padding-bottom: 10px;
112
+ }
113
+ }
114
+ }
115
+ }
116
+ }
117
+
118
+ .omgf-optimize-fonts-description {
119
+ .omgf-optimize-fonts-pros {
120
+ margin-right: 10px;
121
+ }
122
+
123
+ .omgf-optimize-fonts-pros,
124
+ .omgf-optimize-fonts-cons {
125
+ text-align: left;
126
+ width: 48%;
127
+ display: inline-block;
128
+ vertical-align: top;
129
+
130
+ span:before {
131
+ vertical-align: -4px;
132
+ }
133
+ }
134
+
135
+ label {
136
+ font-size: 18px;
137
+ font-weight: bold;
138
+ }
139
+
140
+ #omgf_manual_optimize_url {
141
+ font-size: 18px;
142
+ padding: 0 15px;
143
+ margin-left: 10px;
144
+ }
145
+ }
146
+
147
+ .omgf-optimize-fonts-tooltip {
148
+ padding: 0 15px 5px;
149
+ }
150
+
151
+ p,
152
+ ul {
153
+ text-align: justify;
154
+ }
155
+ }
156
+
157
  /**
158
  * Welcome block
159
  */
assets/js/omgf-admin.js CHANGED
@@ -13,82 +13,103 @@
13
  * @url : https://daan.dev
14
  * * * * * * * * * * * * * * * * * * * */
15
 
16
- jQuery(document).ready(function ($) {
17
  var omgf_admin = {
18
- empty_cache_directory_xhr: false,
19
- optimize_xhr: false,
20
-
21
  /**
22
  * Initialize all on click events.
23
  */
24
- init: function () {
 
 
 
 
25
  // Buttons
26
  $('.omgf-empty').on('click', this.empty_cache_directory);
27
- $('#omgf-optimize').on('click', this.optimize);
28
  },
29
-
30
  /**
31
- * Empty queue, db and cache directory.
32
  */
33
- empty_cache_directory: function () {
34
- if (omgf_admin.empty_cache_directory_xhr) {
35
- omgf_admin.empty_cache_directory_xhr.abort();
 
 
 
 
36
  }
37
-
38
- omgf_admin.empty_cache_directory_xhr = $.ajax({
39
- type: 'POST',
40
- url: ajaxurl,
41
- data: {
42
- action: 'omgf_ajax_empty_dir'
43
- },
44
- beforeSend: function () {
45
- omgf_admin.show_loader();
46
- },
47
- complete: function() {
48
- location.reload();
49
- }
50
- });
51
  },
52
 
53
  /**
54
- *
55
  */
56
- optimize: function () {
57
- if (omgf_admin.optimize_xhr) {
58
- omgf_admin.optimize_xhr.abort();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
  }
60
 
61
- omgf_admin.optimize_xhr = $.ajax({
62
- type: 'GET',
63
- url: ajaxurl,
64
- data: {
65
- action: 'omgf_ajax_optimize'
66
  },
67
- beforeSend: function() {
68
  omgf_admin.show_loader();
69
  },
70
- complete: function() {
71
- $('.omgf-loading').html('<span>All done!</span>');
72
-
73
- setTimeout(
74
- location.reload(),
75
- 3000
76
- )
77
  }
78
  });
79
  },
80
-
 
 
 
 
81
  /**
82
  *
83
  */
84
- show_loader: function () {
85
  $('#wpcontent').append('<div class="omgf-loading"><span class="spinner is-active"></span></div>');
86
  }
87
  };
88
-
89
  omgf_admin.init();
90
-
91
- $('#omgf_relative_url').click(function () {
92
  if (this.checked === true) {
93
  $('#omgf_cdn_url').prop('disabled', true);
94
  } else {
13
  * @url : https://daan.dev
14
  * * * * * * * * * * * * * * * * * * * */
15
 
16
+ jQuery(document).ready(function($) {
17
  var omgf_admin = {
18
+ empty_cache_directory_xhr : false,
19
+ optimize_xhr : false,
20
+
21
  /**
22
  * Initialize all on click events.
23
  */
24
+ init : function() {
25
+ // Settings
26
+ $('input[name="omgf_optimization_mode"]').on('click', this.toggle_optimization_mode_content);
27
+ $('tbody input.unload').on('change', this.unload_stylesheets);
28
+
29
  // Buttons
30
  $('.omgf-empty').on('click', this.empty_cache_directory);
31
+ $('#omgf-optimize-settings-form').submit(this.show_loader_before_submit);
32
  },
33
+
34
  /**
35
+ *
36
  */
37
+ toggle_optimization_mode_content : function() {
38
+ if (this.value == 'manual') {
39
+ $('.omgf-optimize-fonts-manual').show();
40
+ $('.omgf-optimize-fonts-automatic').hide();
41
+ } else {
42
+ $('.omgf-optimize-fonts-automatic').show();
43
+ $('.omgf-optimize-fonts-manual').hide();
44
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  },
46
 
47
  /**
48
+ * Populates the omgf_unload_stylesheets hidden field.
49
  */
50
+ unload_stylesheets : function() {
51
+ var handle = $(this).closest('tbody');
52
+ var id = handle[0].id;
53
+ var checked = $('tbody' + '#' + id + ' input.unload:checked').length;
54
+ var total = $('tbody' + '#' + id + ' input.unload').length;
55
+ var unloaded_stylesheets_option = $('#omgf_unload_stylesheets');
56
+ var unloaded_stylesheets = unloaded_stylesheets_option.val().split(',');
57
+
58
+ if (checked === total) {
59
+ if (unloaded_stylesheets.indexOf(id) === -1) {
60
+ unloaded_stylesheets.push(id);
61
+ }
62
+
63
+ unloaded_stylesheets.join();
64
+
65
+ unloaded_stylesheets_option.val(unloaded_stylesheets);
66
+ } else {
67
+ position = unloaded_stylesheets.indexOf(id);
68
+
69
+ if ( ~position ) unloaded_stylesheets.splice(position, 1);
70
+
71
+ unloaded_stylesheets_option.val(unloaded_stylesheets);
72
+ }
73
+ },
74
+
75
+ /**
76
+ * Empty queue, db and cache directory.
77
+ */
78
+ empty_cache_directory : function() {
79
+ if (omgf_admin.empty_cache_directory_xhr) {
80
+ omgf_admin.empty_cache_directory_xhr.abort();
81
  }
82
 
83
+ omgf_admin.empty_cache_directory_xhr = $.ajax({
84
+ type : 'POST',
85
+ url : ajaxurl,
86
+ data : {
87
+ action : 'omgf_ajax_empty_dir'
88
  },
89
+ beforeSend : function() {
90
  omgf_admin.show_loader();
91
  },
92
+ complete : function() {
93
+ location.reload();
 
 
 
 
 
94
  }
95
  });
96
  },
97
+
98
+ show_loader_before_submit : function(e) {
99
+ omgf_admin.show_loader();
100
+ },
101
+
102
  /**
103
  *
104
  */
105
+ show_loader : function() {
106
  $('#wpcontent').append('<div class="omgf-loading"><span class="spinner is-active"></span></div>');
107
  }
108
  };
109
+
110
  omgf_admin.init();
111
+
112
+ $('#omgf_relative_url').click(function() {
113
  if (this.checked === true) {
114
  $('#omgf_cdn_url').prop('disabled', true);
115
  } else {
host-webfonts-local.php CHANGED
@@ -3,8 +3,8 @@
3
  * @formatter:off
4
  * Plugin Name: OMGF
5
  * Plugin URI: https://daan.dev/wordpress-plugins/host-google-fonts-locally
6
- * Description: Minimize DNS requests and leverage browser cache by automatically saving Google Fonts to your server and removing the external Google Fonts.
7
- * Version: 4.1.3
8
  * Author: Daan (from Fast FW Press)
9
  * Author URI: https://ffwp.dev
10
  * License: GPL2v2 or later
@@ -19,7 +19,8 @@ defined( 'ABSPATH' ) || exit;
19
  */
20
  define( 'OMGF_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
21
  define( 'OMGF_PLUGIN_FILE', __FILE__ );
22
- define( 'OMGF_STATIC_VERSION', '4.1.3' );
 
23
 
24
  /**
25
  * Takes care of loading classes on demand.
3
  * @formatter:off
4
  * Plugin Name: OMGF
5
  * Plugin URI: https://daan.dev/wordpress-plugins/host-google-fonts-locally
6
+ * Description: Minimize DNS requests, leverage browser cache and speed up WordPress by saving Google Fonts to your server and removing external Google Fonts requests.
7
+ * Version: 4.2.0
8
  * Author: Daan (from Fast FW Press)
9
  * Author URI: https://ffwp.dev
10
  * License: GPL2v2 or later
19
  */
20
  define( 'OMGF_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
21
  define( 'OMGF_PLUGIN_FILE', __FILE__ );
22
+ define( 'OMGF_PLUGIN_BASENAME', plugin_basename(OMGF_PLUGIN_FILE));
23
+ define( 'OMGF_STATIC_VERSION', '4.2.0' );
24
 
25
  /**
26
  * Takes care of loading classes on demand.
includes/admin/class-notice.php CHANGED
@@ -24,9 +24,6 @@ class OMGF_Admin_Notice
24
  /** @var array $notices */
25
  public static $notices = [];
26
 
27
- /** @var string $plugin_text_domain */
28
- private static $plugin_text_domain = 'host-webfonts-local';
29
-
30
  /**
31
  * @param $message
32
  * @param string $type (info|warning|error|success)
@@ -103,29 +100,4 @@ class OMGF_Admin_Notice
103
 
104
  delete_transient( self::OMGF_ADMIN_NOTICE_TRANSIENT );
105
  }
106
-
107
- /**
108
- *
109
- */
110
- public static function optimization_finished () {
111
- self::set_notice(
112
- __( 'OMGF has finished optimizing your Google Fonts. Enjoy! :-)', self::$plugin_text_domain ),
113
- 'omgf-finished-optimizing',
114
- false
115
- );
116
-
117
- self::set_notice(
118
- '<em>' . __( 'If you\'re using any CSS minify/combine and/or Full Page Caching plugins, don\'t forget to flush their caches.', self::$plugin_text_domain ) . '</em>',
119
- 'omgf-optimize-plugin-notice',
120
- false,
121
- 'info'
122
- );
123
-
124
- self::set_notice(
125
- __( 'OMGF will keep running silently in the background and will generate additional stylesheets when other Google Fonts are found on any of your pages.', self::$plugin_text_domain ),
126
- 'omgf-optimize-background',
127
- false,
128
- 'info'
129
- );
130
- }
131
  }
24
  /** @var array $notices */
25
  public static $notices = [];
26
 
 
 
 
27
  /**
28
  * @param $message
29
  * @param string $type (info|warning|error|success)
100
 
101
  delete_transient( self::OMGF_ADMIN_NOTICE_TRANSIENT );
102
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103
  }
includes/admin/class-settings.php CHANGED
@@ -18,17 +18,20 @@ defined( 'ABSPATH' ) || exit;
18
 
19
  class OMGF_Admin_Settings extends OMGF_Admin
20
  {
21
- const FFWP_WORDPRESS_PLUGINS_OMGF_PRO = 'https://ffwp.dev/wordpress/omgf-pro/';
22
-
23
  /**
24
  * Settings Fields
25
  */
26
- const OMGF_SETTINGS_FIELD_BASIC = 'omgf-basic-settings';
27
- const OMGF_SETTINGS_FIELD_ADVANCED = 'omgf-advanced-settings';
 
28
 
29
  /**
30
  * Option Values
31
  */
 
 
 
 
32
  const OMGF_FONT_PROCESSING_OPTIONS = [
33
  'replace' => 'Replace (default)',
34
  'remove' => 'Remove only'
@@ -72,25 +75,36 @@ class OMGF_Admin_Settings extends OMGF_Admin
72
  ];
73
 
74
  /**
75
- *
76
  */
77
- const OMGF_OPTIMIZATION_COMPLETE = 'omgf_optimization_complete';
 
 
 
 
 
 
 
78
 
79
  /**
80
- * Basic Settings
81
  */
82
- const OMGF_BASIC_SETTING_FONT_PROCESSING = 'omgf_font_processing';
83
- const OMGF_BASIC_SETTING_DISPLAY_OPTION = 'omgf_display_option';
84
- const OMGF_BASIC_SETTING_CACHE_PATH = 'omgf_cache_dir';
85
- const OMGF_BASIC_SETTING_OPTIMIZE_EDIT_ROLES = 'omgf_optimize_edit_roles';
86
 
87
  /**
88
  * Advanced Settings
89
  */
90
- const OMGF_ADV_SETTING_CACHE_URI = 'omgf_cache_uri';
91
- const OMGF_ADV_SETTING_CDN_URL = 'omgf_cdn_url';
92
- const OMGF_ADV_SETTING_UNINSTALL = 'omgf_uninstall';
93
- const OMGF_ADV_SETTING_RELATIVE_URL = 'omgf_relative_url';
 
 
 
 
 
 
 
94
 
95
  /** @var string $active_tab */
96
  private $active_tab;
@@ -107,7 +121,7 @@ class OMGF_Admin_Settings extends OMGF_Admin
107
  public function __construct () {
108
  parent::__construct();
109
 
110
- $this->active_tab = isset( $_GET['tab'] ) ? $_GET['tab'] : self::OMGF_SETTINGS_FIELD_BASIC;
111
  $this->page = isset( $_GET['page'] ) ? $_GET['page'] : '';
112
 
113
  add_action( 'admin_menu', [ $this, 'create_menu' ] );
@@ -118,12 +132,14 @@ class OMGF_Admin_Settings extends OMGF_Admin
118
  }
119
 
120
  // Tabs
121
- add_action( 'omgf_settings_tab', [ $this, 'basic_settings_tab' ], 0 );
122
- add_action( 'omgf_settings_tab', [ $this, 'advanced_settings_tab' ], 1 );
 
123
 
124
  // Content
125
- add_action( 'omgf_settings_content', [ $this, 'basic_settings_content' ], 0 );
126
- add_action( 'omgf_settings_content', [ $this, 'advanced_settings_content' ], 1 );
 
127
  }
128
 
129
  /**
@@ -181,9 +197,11 @@ class OMGF_Admin_Settings extends OMGF_Admin
181
  * @throws ReflectionException
182
  */
183
  public function register_settings () {
184
- if ( $this->active_tab !== self::OMGF_SETTINGS_FIELD_BASIC
185
- && $this->active_tab !== self::OMGF_SETTINGS_FIELD_ADVANCED ) {
186
- $this->active_tab = self::OMGF_SETTINGS_FIELD_BASIC;
 
 
187
  }
188
 
189
  foreach ( $this->get_settings() as $constant => $value ) {
@@ -205,11 +223,14 @@ class OMGF_Admin_Settings extends OMGF_Admin
205
  $constants = apply_filters( 'omgf_settings_constants', $reflection->getConstants() );
206
 
207
  switch ( $this->active_tab ) {
208
- case ( self::OMGF_SETTINGS_FIELD_BASIC ):
209
- $needle = 'OMGF_BASIC_SETTING_';
 
 
 
210
  break;
211
  default:
212
- $needle = 'OMGF_ADV_SETTING';
213
  }
214
 
215
  return array_filter(
@@ -221,11 +242,15 @@ class OMGF_Admin_Settings extends OMGF_Admin
221
  );
222
  }
223
 
 
 
 
 
224
  /**
225
  * Add Basic Settings Tab to Settings Screen.
226
  */
227
- public function basic_settings_tab () {
228
- $this->generate_tab( self::OMGF_SETTINGS_FIELD_BASIC, 'dashicons-analytics', __( 'Basic Settings', $this->plugin_text_domain ) );
229
  }
230
 
231
  /**
@@ -255,14 +280,21 @@ class OMGF_Admin_Settings extends OMGF_Admin
255
  * @return string
256
  */
257
  private function generate_tab_link ( $tab ) {
258
- return admin_url( "options-general.php?page=optimize-webfonts&tab=$tab" );
 
 
 
 
 
 
 
259
  }
260
 
261
  /**
262
  * Render Basic Settings content
263
  */
264
- public function basic_settings_content () {
265
- $this->do_settings_content( self::OMGF_SETTINGS_FIELD_BASIC );
266
  }
267
 
268
  /**
@@ -280,7 +312,8 @@ class OMGF_Admin_Settings extends OMGF_Admin
280
  return;
281
  }
282
  ?>
283
- <form id="<?= $field; ?>-form" name="omgf-settings-form" method="post" action="<?= admin_url( 'options.php?tab=' . $this->active_tab ); ?>">
 
284
  <?php
285
  settings_fields( $field );
286
  do_settings_sections( $field );
@@ -304,7 +337,7 @@ class OMGF_Admin_Settings extends OMGF_Admin
304
  * @return mixed
305
  */
306
  public function create_settings_link ( $links ) {
307
- $adminUrl = admin_url() . 'options-general.php?page=optimize-webfonts';
308
  $settingsLink = "<a href='$adminUrl'>" . __( 'Settings' ) . "</a>";
309
  array_push( $links, $settingsLink );
310
 
18
 
19
  class OMGF_Admin_Settings extends OMGF_Admin
20
  {
 
 
21
  /**
22
  * Settings Fields
23
  */
24
+ const OMGF_SETTINGS_FIELD_OPTIMIZE = 'omgf-optimize-settings';
25
+ const OMGF_SETTINGS_FIELD_DETECTION = 'omgf-detection-settings';
26
+ const OMGF_SETTINGS_FIELD_ADVANCED = 'omgf-advanced-settings';
27
 
28
  /**
29
  * Option Values
30
  */
31
+ const OMGF_OPTIMIZATION_MODE = [
32
+ 'manual' => 'Manual (default)',
33
+ 'auto' => 'Automatic'
34
+ ];
35
  const OMGF_FONT_PROCESSING_OPTIONS = [
36
  'replace' => 'Replace (default)',
37
  'remove' => 'Remove only'
75
  ];
76
 
77
  /**
78
+ * Optimize Fonts
79
  */
80
+ const OMGF_OPTIMIZE_SETTING_DISPLAY_OPTION = 'omgf_display_option';
81
+ const OMGF_OPTIMIZE_SETTING_MANUAL_OPTIMIZE_URL = 'omgf_manual_optimize_url';
82
+ const OMGF_OPTIMIZE_SETTING_OPTIMIZATION_MODE = 'omgf_optimization_mode';
83
+ const OMGF_OPTIMIZE_SETTING_OPTIMIZED_FONTS = 'omgf_optimized_fonts';
84
+ const OMGF_OPTIMIZE_SETTING_OPTIMIZE_EDIT_ROLES = 'omgf_optimize_edit_roles';
85
+ const OMGF_OPTIMIZE_SETTING_PRELOAD_FONTS = 'omgf_preload_fonts';
86
+ const OMGF_OPTIMIZE_SETTING_UNLOAD_FONTS = 'omgf_unload_fonts';
87
+ const OMGF_OPTIMIZE_SETTING_UNLOAD_STYLESHEETS = 'omgf_unload_stylesheets';
88
 
89
  /**
90
+ * Detection Settings
91
  */
92
+ const OMGF_DETECTION_SETTING_FONT_PROCESSING = 'omgf_font_processing';
 
 
 
93
 
94
  /**
95
  * Advanced Settings
96
  */
97
+ const OMGF_ADV_SETTING_CACHE_PATH = 'omgf_cache_dir';
98
+ const OMGF_ADV_SETTING_CACHE_URI = 'omgf_cache_uri';
99
+ const OMGF_ADV_SETTING_CDN_URL = 'omgf_cdn_url';
100
+ const OMGF_ADV_SETTING_UNINSTALL = 'omgf_uninstall';
101
+ const OMGF_ADV_SETTING_RELATIVE_URL = 'omgf_relative_url';
102
+
103
+ /**
104
+ * Miscellaneous
105
+ */
106
+ const OMGF_OPTIONS_GENERAL_PAGE_OPTIMIZE_WEBFONTS = 'options-general.php?page=optimize-webfonts';
107
+ const FFWP_WORDPRESS_PLUGINS_OMGF_PRO = 'https://ffwp.dev/wordpress/omgf-pro/';
108
 
109
  /** @var string $active_tab */
110
  private $active_tab;
121
  public function __construct () {
122
  parent::__construct();
123
 
124
+ $this->active_tab = isset( $_GET['tab'] ) ? $_GET['tab'] : self::OMGF_SETTINGS_FIELD_OPTIMIZE;
125
  $this->page = isset( $_GET['page'] ) ? $_GET['page'] : '';
126
 
127
  add_action( 'admin_menu', [ $this, 'create_menu' ] );
132
  }
133
 
134
  // Tabs
135
+ add_action( 'omgf_settings_tab', [ $this, 'optimize_fonts_tab' ], 0 );
136
+ add_action( 'omgf_settings_tab', [ $this, 'detection_settings_tab' ], 1 );
137
+ add_action( 'omgf_settings_tab', [ $this, 'advanced_settings_tab' ], 2 );
138
 
139
  // Content
140
+ add_action( 'omgf_settings_content', [ $this, 'optimize_fonts_content' ], 0 );
141
+ add_action( 'omgf_settings_content', [ $this, 'detection_settings_content' ], 1 );
142
+ add_action( 'omgf_settings_content', [ $this, 'advanced_settings_content' ], 2 );
143
  }
144
 
145
  /**
197
  * @throws ReflectionException
198
  */
199
  public function register_settings () {
200
+ if ( $this->active_tab !== self::OMGF_SETTINGS_FIELD_OPTIMIZE
201
+ && $this->active_tab !== self::OMGF_SETTINGS_FIELD_DETECTION
202
+ && $this->active_tab !== self::OMGF_SETTINGS_FIELD_ADVANCED
203
+ ) {
204
+ $this->active_tab = self::OMGF_SETTINGS_FIELD_OPTIMIZE;
205
  }
206
 
207
  foreach ( $this->get_settings() as $constant => $value ) {
223
  $constants = apply_filters( 'omgf_settings_constants', $reflection->getConstants() );
224
 
225
  switch ( $this->active_tab ) {
226
+ case ( self::OMGF_SETTINGS_FIELD_DETECTION ):
227
+ $needle = 'OMGF_DETECTION_SETTING_';
228
+ break;
229
+ case ( self::OMGF_SETTINGS_FIELD_ADVANCED ):
230
+ $needle = 'OMGF_ADV_SETTING_';
231
  break;
232
  default:
233
+ $needle = 'OMGF_OPTIMIZE_SETTING_';
234
  }
235
 
236
  return array_filter(
242
  );
243
  }
244
 
245
+ public function optimize_fonts_tab () {
246
+ $this->generate_tab( self::OMGF_SETTINGS_FIELD_OPTIMIZE, 'dashicons-performance', __( 'Optimize Fonts', $this->plugin_text_domain ) );
247
+ }
248
+
249
  /**
250
  * Add Basic Settings Tab to Settings Screen.
251
  */
252
+ public function detection_settings_tab () {
253
+ $this->generate_tab( self::OMGF_SETTINGS_FIELD_DETECTION, 'dashicons-search', __( 'Detection Settings', $this->plugin_text_domain ) );
254
  }
255
 
256
  /**
280
  * @return string
281
  */
282
  private function generate_tab_link ( $tab ) {
283
+ return admin_url( self::OMGF_OPTIONS_GENERAL_PAGE_OPTIMIZE_WEBFONTS . "&tab=$tab" );
284
+ }
285
+
286
+ /**
287
+ *
288
+ */
289
+ public function optimize_fonts_content () {
290
+ $this->do_settings_content( self::OMGF_SETTINGS_FIELD_OPTIMIZE );
291
  }
292
 
293
  /**
294
  * Render Basic Settings content
295
  */
296
+ public function detection_settings_content () {
297
+ $this->do_settings_content( self::OMGF_SETTINGS_FIELD_DETECTION );
298
  }
299
 
300
  /**
312
  return;
313
  }
314
  ?>
315
+ <form id="<?= $field; ?>-form" name="omgf-settings-form" method="post" action="<?= admin_url( 'options.php?tab=' . $this->active_tab ); ?>"
316
+ autocomplete="off">
317
  <?php
318
  settings_fields( $field );
319
  do_settings_sections( $field );
337
  * @return mixed
338
  */
339
  public function create_settings_link ( $links ) {
340
+ $adminUrl = admin_url() . self::OMGF_OPTIONS_GENERAL_PAGE_OPTIMIZE_WEBFONTS;
341
  $settingsLink = "<a href='$adminUrl'>" . __( 'Settings' ) . "</a>";
342
  array_push( $links, $settingsLink );
343
 
includes/admin/settings/class-advanced.php CHANGED
@@ -32,9 +32,7 @@ class OMGF_Admin_Settings_Advanced extends OMGF_Admin_Settings_Builder
32
  add_filter( 'omgf_advanced_settings_content', [ $this, 'do_before' ], 20 );
33
 
34
  // Settings
35
- add_filter( 'omgf_advanced_settings_content', [ $this, 'do_promo_fonts_processing' ], 50 );
36
- add_filter( 'omgf_advanced_settings_content', [ $this, 'do_promo_process_resource_hints' ], 60 );
37
- add_filter( 'omgf_advanced_settings_content', [ $this, 'do_promo_force_subsets' ], 70 );
38
  add_filter( 'omgf_advanced_settings_content', [ $this, 'do_cdn_url' ], 80 );
39
  add_filter( 'omgf_advanced_settings_content', [ $this, 'do_cache_uri' ], 90 );
40
  add_filter( 'omgf_advanced_settings_content', [ $this, 'do_relative_url' ], 100 );
@@ -50,6 +48,7 @@ class OMGF_Admin_Settings_Advanced extends OMGF_Admin_Settings_Builder
50
  public function do_description () {
51
  ?>
52
  <p>
 
53
  </p>
54
  <?php
55
  }
@@ -57,81 +56,26 @@ class OMGF_Admin_Settings_Advanced extends OMGF_Admin_Settings_Builder
57
  /**
58
  *
59
  */
60
- public function do_promo_fonts_processing () {
61
- ?>
62
- <tr>
63
- <th scope="row"><?= __( 'Google Fonts Processing (Pro)', $this->plugin_text_domain ); ?></th>
64
- <td>
65
- <fieldset id="" class="scheme-list">
66
- <?php foreach ( $this->fonts_processing_pro_options() as $name => $data ): ?>
67
- <?php
68
- $checked = defined( strtoupper( $name ) ) ? constant( strtoupper( $name ) ) : false;
69
- $disabled = apply_filters( $name . '_setting_disabled', true ) ? 'disabled' : '';
70
- ?>
71
- <label for="<?= $name; ?>">
72
- <input type="checkbox" name="<?= $name; ?>" <?= $checked ? 'checked="checked"' : ''; ?> <?= $disabled; ?> /><?= $data['label']; ?>
73
- &nbsp;
74
- </label>
75
- <?php endforeach; ?>
76
- </fieldset>
77
- <p class="description">
78
- <?= $this->promo; ?>
79
- <ul>
80
- <?php foreach ( $this->fonts_processing_pro_options() as $name => $data ): ?>
81
- <li><strong><?= $data['label']; ?></strong>: <?= $data['description']; ?></li>
82
- <?php endforeach; ?>
83
- </ul>
84
- </p>
85
- </td>
86
- </tr>
87
- <?php
88
- }
89
-
90
- /**
91
- * @return array
92
- */
93
- private function fonts_processing_pro_options () {
94
- return [
95
- 'omgf_pro_process_stylesheets' => [
96
- 'label' => __( 'Process Stylesheets', $this->plugin_text_domain ),
97
- 'description' => __( 'Process stylesheets loaded from <code>fonts.googleapis.com</code> or <code>fonts.gstatic.com</code>.', $this->plugin_text_domain )
98
- ],
99
- 'omgf_pro_process_inline_styles' => [
100
- 'label' => __( 'Process Inline Styles', $this->plugin_text_domain ),
101
- 'description' => __( 'Process all <code>@font-face</code> and <code>@import</code> rules loading Google Fonts.', $this->plugin_text_domain )
102
- ],
103
- 'omgf_pro_process_webfont_loader' => [
104
- 'label' => __( 'Process Webfont Loader', $this->plugin_text_domain ),
105
- 'description' => __( 'Process <code>webfont.js</code> libraries and the corresponding configuration defining which Google Fonts to load.', $this->plugin_text_domain )
106
- ]
107
- ];
108
- }
109
-
110
- /**
111
- *
112
- */
113
- public function do_promo_process_resource_hints () {
114
- $this->do_checkbox(
115
- __( 'Remove Resource Hints (Pro)', $this->plugin_text_domain ),
116
- 'omgf_pro_process_resource_hints',
117
- defined( 'OMGF_PRO_PROCESS_RESOURCE_HINTS' ) ? OMGF_PRO_PROCESS_RESOURCE_HINTS : false,
118
- __( 'Remove all <code>link</code> elements with a <code>rel</code> attribute value of <code>dns-prefetch</code>, <code>preload</code> or <code>preconnect</code> pointing to <code>fonts.googleapis.com</code> or <code>fonts.gstatic.com</code>.', $this->plugin_text_domain ) . ' ' . $this->promo,
119
- true
120
  );
121
  }
122
 
123
  /**
124
  *
125
  */
126
- public function do_promo_force_subsets () {
127
- $this->do_select(
128
- __( 'Force Subsets (Pro)', $this->plugin_text_domain ),
129
- 'omgf_pro_force_subsets',
130
- OMGF_Admin_Settings::OMGF_FORCE_SUBSETS_OPTIONS,
131
- defined( 'OMGF_PRO_FORCE_SUBSETS' ) ? OMGF_PRO_FORCE_SUBSETS : [],
132
- __( 'If a theme or plugin loads subsets you don\'t need, use this option to force all Google Fonts to be loaded in the selected subsets.', $this->plugin_text_domain ) . ' ' . $this->promo,
133
- true,
134
- true
135
  );
136
  }
137
 
@@ -144,7 +88,7 @@ class OMGF_Admin_Settings_Advanced extends OMGF_Admin_Settings_Builder
144
  OMGF_Admin_Settings::OMGF_ADV_SETTING_CACHE_URI,
145
  __( 'e.g. /app/uploads/omgf', $this->plugin_text_domain ),
146
  OMGF_CACHE_URI,
147
- __( 'The relative path to serve font files from. Useful for when you\'re using security through obscurity plugins, such as WP Hide. If left empty, the cache directory specified under Basic Settings will be used.', $this->plugin_text_domain )
148
  );
149
  }
150
 
@@ -160,19 +104,6 @@ class OMGF_Admin_Settings_Advanced extends OMGF_Admin_Settings_Builder
160
  );
161
  }
162
 
163
- /**
164
- *
165
- */
166
- public function do_cdn_url () {
167
- $this->do_text(
168
- __( 'Serve fonts from CDN', $this->plugin_text_domain ),
169
- OMGF_Admin_Settings::OMGF_ADV_SETTING_CDN_URL,
170
- __( 'e.g. https://cdn.mydomain.com', $this->plugin_text_domain ),
171
- OMGF_CDN_URL,
172
- __( "If you're using a CDN, enter the URL here incl. protocol (e.g. <code>https://</code>.) Leave empty when using CloudFlare.", $this->plugin_text_domain )
173
- );
174
- }
175
-
176
  /**
177
  *
178
  */
32
  add_filter( 'omgf_advanced_settings_content', [ $this, 'do_before' ], 20 );
33
 
34
  // Settings
35
+ add_filter( 'omgf_advanced_settings_content', [ $this, 'do_cache_dir' ], 70 );
 
 
36
  add_filter( 'omgf_advanced_settings_content', [ $this, 'do_cdn_url' ], 80 );
37
  add_filter( 'omgf_advanced_settings_content', [ $this, 'do_cache_uri' ], 90 );
38
  add_filter( 'omgf_advanced_settings_content', [ $this, 'do_relative_url' ], 100 );
48
  public function do_description () {
49
  ?>
50
  <p>
51
+ <?= __( 'If you require the downloaded/generated files to be saved in a different location or served from a different resource (e.g. a CDN) or path, use these settings to make OMGF work with your configuration.', $this->plugin_text_domain ); ?>
52
  </p>
53
  <?php
54
  }
56
  /**
57
  *
58
  */
59
+ public function do_cache_dir () {
60
+ $this->do_text(
61
+ __( 'Save font files to...', $this->plugin_text_domain ),
62
+ OMGF_Admin_Settings::OMGF_ADV_SETTING_CACHE_PATH,
63
+ __( 'e.g. /uploads/omgf', $this->plugin_text_domain ),
64
+ OMGF_CACHE_PATH,
65
+ __( "The folder (inside <code>wp-content</code>) where font files should be stored. Give each site a unique value if you're using Multisite. Defaults to <code>/uploads/omgf</code>. After changing this setting, the folder will be created if it doesn't exist and existing files will be moved automatically.", $this->plugin_text_domain )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
  );
67
  }
68
 
69
  /**
70
  *
71
  */
72
+ public function do_cdn_url () {
73
+ $this->do_text(
74
+ __( 'Serve fonts from CDN', $this->plugin_text_domain ),
75
+ OMGF_Admin_Settings::OMGF_ADV_SETTING_CDN_URL,
76
+ __( 'e.g. https://cdn.mydomain.com', $this->plugin_text_domain ),
77
+ OMGF_CDN_URL,
78
+ __( "If you're using a CDN, enter the URL here incl. protocol (e.g. <code>https://</code>.) Leave empty when using CloudFlare.", $this->plugin_text_domain )
 
 
79
  );
80
  }
81
 
88
  OMGF_Admin_Settings::OMGF_ADV_SETTING_CACHE_URI,
89
  __( 'e.g. /app/uploads/omgf', $this->plugin_text_domain ),
90
  OMGF_CACHE_URI,
91
+ __( 'The relative path to serve font files from. Useful for when you\'re using security through obscurity plugins, such as WP Hide. If left empty, the cache directory specified in <strong>Save font files to...</strong> will be used.', $this->plugin_text_domain )
92
  );
93
  }
94
 
104
  );
105
  }
106
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107
  /**
108
  *
109
  */
includes/admin/settings/class-basic.php DELETED
@@ -1,133 +0,0 @@
1
- <?php
2
- /* * * * * * * * * * * * * * * * * * * * *
3
- *
4
- * ██████╗ ███╗ ███╗ ██████╗ ███████╗
5
- * ██╔═══██╗████╗ ████║██╔════╝ ██╔════╝
6
- * ██║ ██║██╔████╔██║██║ ███╗█████╗
7
- * ██║ ██║██║╚██╔╝██║██║ ██║██╔══╝
8
- * ╚██████╔╝██║ ╚═╝ ██║╚██████╔╝██║
9
- * ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝
10
- *
11
- * @package : OMGF
12
- * @author : Daan van den Bergh
13
- * @copyright: (c) 2020 Daan van den Bergh
14
- * @url : https://daan.dev
15
- * * * * * * * * * * * * * * * * * * * */
16
-
17
- defined( 'ABSPATH' ) || exit;
18
-
19
- class OMGF_Admin_Settings_Basic extends OMGF_Admin_Settings_Builder
20
- {
21
- public function __construct () {
22
- parent::__construct();
23
-
24
- $this->title = __( 'Basic Settings', $this->plugin_text_domain );
25
-
26
- // Open
27
- add_filter( 'omgf_basic_settings_content', [ $this, 'do_title' ], 10 );
28
- add_filter( 'omgf_basic_settings_content', [ $this, 'do_description' ], 15 );
29
- add_filter( 'omgf_basic_settings_content', [ $this, 'do_before' ], 20 );
30
-
31
- // Settings
32
- add_filter( 'omgf_basic_settings_content', [ $this, 'do_process_google_fonts' ], 30 );
33
- add_filter( 'omgf_basic_settings_content', [ $this, 'do_promo_advanced_processing' ], 40 );
34
- add_filter( 'omgf_basic_settings_content', [ $this, 'do_display_option' ], 50 );
35
- add_filter( 'omgf_basic_settings_content', [ $this, 'do_promo_combine_requests' ], 60 );
36
- add_filter( 'omgf_basic_settings_content', [ $this, 'do_cache_dir' ], 70 );
37
- add_filter( 'omgf_basic_settings_content', [ $this, 'do_optimize_edit_roles' ], 80 );
38
-
39
- // Close
40
- add_filter( 'omgf_basic_settings_content', [ $this, 'do_after' ], 100 );
41
- }
42
-
43
- /**
44
- * Description
45
- */
46
- public function do_description () {
47
- ?>
48
- <p>
49
- * <?= __( 'If you\'re looking to replace your Google Fonts for locally hosted copies, then the default settings will suffice. OMGF will run silently in the background and download any Google Fonts while you and/or your visitors are browsing your site.', $this->plugin_text_domain ); ?>
50
- </p>
51
- <p>
52
- <?= __( 'If <strong>Google Fonts Processing</strong> is set to Replace, loading the locally hosted stylesheet for the first time (or after emptying OMGF\'s cache directory) might take a few seconds. This depends on your server\'s capacity and the size of the stylesheet. This is because OMGF\'s Download API captures the request and automatically downloads the fonts, before serving the local copy. Once the stylesheet and fonts are downloaded, every consecutive request will be fast again.', $this->plugin_text_domain ); ?>
53
- </p>
54
- <?php
55
- }
56
-
57
- /**
58
- *
59
- */
60
- public function do_process_google_fonts () {
61
- $this->do_select(
62
- __( 'Google Fonts Processing', $this->plugin_text_domain ),
63
- OMGF_Admin_Settings::OMGF_BASIC_SETTING_FONT_PROCESSING,
64
- OMGF_Admin_Settings::OMGF_FONT_PROCESSING_OPTIONS,
65
- OMGF_FONT_PROCESSING,
66
- sprintf( __( "Choose whether OMGF should (find, download and) <strong>replace</strong> all Google Fonts, or just <strong>remove</strong> them. Choosing Remove will force WordPress to fallback to system fonts or install your own.", $this->plugin_text_domain ), OMGF_Admin_Settings::FFWP_WORDPRESS_PLUGINS_OMGF_PRO )
67
- );
68
- }
69
-
70
- /**
71
- *
72
- */
73
- public function do_promo_advanced_processing () {
74
- $this->do_checkbox(
75
- __( 'Advanced Processing (Pro)', $this->plugin_text_domain ),
76
- 'omgf_pro_advanced_processing',
77
- defined( 'OMGF_PRO_ADVANCED_PROCESSING' ) ? true : false,
78
- __( 'By default, OMGF scans for Google Fonts which are registered/enqueued in the <code>wp_enqueue_scripts()</code> action in WordPress\' header (<code>wp_head()</code>). Advanced Processing will process all Google Fonts throughout the entire document. This setting can be tweaked further under Advanced Settings.', $this->plugin_text_domain ) . ' ' . $this->promo,
79
- true
80
- );
81
- }
82
-
83
- /**
84
- *
85
- */
86
- public function do_display_option () {
87
- $this->do_select(
88
- __( 'Font-display option', $this->plugin_text_domain ),
89
- OMGF_Admin_Settings::OMGF_BASIC_SETTING_DISPLAY_OPTION,
90
- OMGF_Admin_Settings::OMGF_FONT_DISPLAY_OPTIONS,
91
- OMGF_DISPLAY_OPTION,
92
- __( 'Select which font-display strategy to use. Defaults to Swap (recommended).', $this->plugin_text_domain )
93
- );
94
- }
95
-
96
- /**
97
- *
98
- */
99
- public function do_promo_combine_requests () {
100
- $this->do_checkbox(
101
- __( 'Combine & Dedupe Google Fonts (Pro)', $this->plugin_text_domain ),
102
- 'omgf_pro_combine_requests',
103
- defined( 'OMGF_PRO_COMBINE_REQUESTS' ) ? true : false,
104
- __( 'Combine and deduplicate multiple font requests into one request. This feature is always on in OMGF Pro and can\'t be disabled.', $this->plugin_text_domain ) . ' ' . $this->promo,
105
- true
106
- );
107
- }
108
-
109
- /**
110
- *
111
- */
112
- public function do_cache_dir () {
113
- $this->do_text(
114
- __( 'Save font files to...', $this->plugin_text_domain ),
115
- OMGF_Admin_Settings::OMGF_BASIC_SETTING_CACHE_PATH,
116
- __( 'e.g. /uploads/omgf', $this->plugin_text_domain ),
117
- OMGF_CACHE_PATH,
118
- __( "The folder (inside <code>wp-content</code>) where font files should be stored. Give each site a unique value if you're using Multisite. Defaults to <code>/uploads/omgf</code>. After changing this setting, the folder will be created if it doesn't exist and existing files will be moved automatically.", $this->plugin_text_domain )
119
- );
120
- }
121
-
122
- /**
123
- *
124
- */
125
- public function do_optimize_edit_roles () {
126
- $this->do_checkbox(
127
- __( 'Optimize fonts for logged in editors/administrators?', $this->plugin_text_domain ),
128
- OMGF_Admin_Settings::OMGF_BASIC_SETTING_OPTIMIZE_EDIT_ROLES,
129
- OMGF_OPTIMIZE_EDIT_ROLES,
130
- __( 'Should only be disabled while debugging/testing, e.g. using a page builder or switching themes.', $this->plugin_text_domain )
131
- );
132
- }
133
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/admin/settings/class-builder.php CHANGED
@@ -33,8 +33,9 @@ class OMGF_Admin_Settings_Builder
33
  * OMGF_Admin_Settings_Builder constructor.
34
  */
35
  public function __construct () {
36
- add_filter('omgf_basic_settings_content', [ $this, 'do_promo' ]);
37
- add_filter('omgf_advanced_settings_content', [ $this, 'do_promo' ]);
 
38
  }
39
 
40
  /**
@@ -73,6 +74,36 @@ class OMGF_Admin_Settings_Builder
73
  <?php
74
  }
75
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76
  /**
77
  * Generate select setting
78
  *
@@ -90,7 +121,7 @@ class OMGF_Admin_Settings_Builder
90
  <?= apply_filters( $name . '_setting_label', $label ); ?>
91
  </th>
92
  <td>
93
- <select name="<?= $name; ?><?= $is_multiselect ? '[]' : ''; ?>" class="<?= str_replace( '_', '-', $name ); ?>" <?= $is_multiselect ? 'size="10" multiple="multiple"' : ''; ?> <?= apply_filters( $name . '_setting_disabled', $disabled ) ? 'disabled' : ''; ?>>
94
  <?php
95
  $options = apply_filters( $name . '_setting_options', $options );
96
  ?>
33
  * OMGF_Admin_Settings_Builder constructor.
34
  */
35
  public function __construct () {
36
+ add_filter('omgf_optimize_settings_content', [ $this, 'do_promo' ]);
37
+ add_filter('omgf_detection_settings_content', [ $this, 'do_promo' ]);
38
+ add_filter('omgf_advanced_settings_content', [ $this, 'do_promo' ]);
39
  }
40
 
41
  /**
74
  <?php
75
  }
76
 
77
+ /**
78
+ * Generate radio setting
79
+ *
80
+ * @param $label
81
+ * @param $inputs
82
+ * @param $name
83
+ * @param $checked
84
+ * @param $description
85
+ */
86
+ public function do_radio($label, $inputs, $name, $checked, $description)
87
+ {
88
+ ?>
89
+ <tr>
90
+ <th scope="row"><?= $label; ?></th>
91
+ <td>
92
+ <?php foreach ($inputs as $option => $option_label): ?>
93
+ <label>
94
+ <input type="radio" class="<?= str_replace('_', '-', $name . '_' . $option); ?>" name="<?= $name; ?>" value="<?= $option; ?>" <?= $option == $checked ? 'checked="checked"' : ''; ?> />
95
+ <?= $option_label; ?>
96
+ </label>
97
+ <br/>
98
+ <?php endforeach; ?>
99
+ <p class="description">
100
+ <?= $description; ?>
101
+ </p>
102
+ </td>
103
+ </tr>
104
+ <?php
105
+ }
106
+
107
  /**
108
  * Generate select setting
109
  *
121
  <?= apply_filters( $name . '_setting_label', $label ); ?>
122
  </th>
123
  <td>
124
+ <select name="<?= $name; ?><?= $is_multiselect ? '[]' : ''; ?>" class="<?= str_replace( '_', '-', $name ); ?>" <?= $is_multiselect ? 'size="8" multiple="multiple"' : ''; ?> <?= apply_filters( $name . '_setting_disabled', $disabled ) ? 'disabled' : ''; ?>>
125
  <?php
126
  $options = apply_filters( $name . '_setting_options', $options );
127
  ?>
includes/admin/settings/class-detection.php ADDED
@@ -0,0 +1,146 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* * * * * * * * * * * * * * * * * * * * *
3
+ *
4
+ * ██████╗ ███╗ ███╗ ██████╗ ███████╗
5
+ * ██╔═══██╗████╗ ████║██╔════╝ ██╔════╝
6
+ * ██║ ██║██╔████╔██║██║ ███╗█████╗
7
+ * ██║ ██║██║╚██╔╝██║██║ ██║██╔══╝
8
+ * ╚██████╔╝██║ ╚═╝ ██║╚██████╔╝██║
9
+ * ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝
10
+ *
11
+ * @package : OMGF
12
+ * @author : Daan van den Bergh
13
+ * @copyright: (c) 2020 Daan van den Bergh
14
+ * @url : https://daan.dev
15
+ * * * * * * * * * * * * * * * * * * * */
16
+
17
+ defined( 'ABSPATH' ) || exit;
18
+
19
+ class OMGF_Admin_Settings_Detection extends OMGF_Admin_Settings_Builder
20
+ {
21
+ public function __construct () {
22
+ parent::__construct();
23
+
24
+ $this->title = __( 'Google Fonts Detection Settings', $this->plugin_text_domain );
25
+
26
+ // Open
27
+ add_filter( 'omgf_detection_settings_content', [ $this, 'do_title' ], 10 );
28
+ add_filter( 'omgf_detection_settings_content', [ $this, 'do_description' ], 15 );
29
+ add_filter( 'omgf_detection_settings_content', [ $this, 'do_before' ], 20 );
30
+
31
+ // Settings
32
+ add_filter( 'omgf_detection_settings_content', [ $this, 'do_process_google_fonts' ], 30 );
33
+ add_filter( 'omgf_detection_settings_content', [ $this, 'do_promo_advanced_processing' ], 40 );
34
+ add_filter( 'omgf_detection_settings_content', [ $this, 'do_promo_fonts_processing' ], 50 );
35
+ add_filter( 'omgf_detection_settings_content', [ $this, 'do_promo_process_resource_hints' ], 60 );
36
+
37
+ // Close
38
+ add_filter( 'omgf_detection_settings_content', [ $this, 'do_after' ], 100 );
39
+ }
40
+
41
+ /**
42
+ * Description
43
+ */
44
+ public function do_description () {
45
+ ?>
46
+ <p>
47
+ <?= __( 'These settings affect OMGF\'s automatic detection mechanism and how it treats the Google Fonts your theme and plugins use. If you want to use OMGF to remove the Google Fonts your WordPress configuration currently uses, set <strong>Google Fonts Processing</strong> to Remove.', $this->plugin_text_domain ); ?>
48
+ </p>
49
+ <p>
50
+ <?= sprintf( __( 'To install additional Google Fonts, a (free) add-on is required, which can be downloaded <a href="%s">here</a> (coming soon).', $this->plugin_text_domain ), '#' ); ?>
51
+ </p>
52
+ <?php
53
+ }
54
+
55
+ /**
56
+ *
57
+ */
58
+ public function do_promo_fonts_processing () {
59
+ ?>
60
+ <tr>
61
+ <th scope="row"><?= __( 'Google Fonts Processing (Pro)', $this->plugin_text_domain ); ?></th>
62
+ <td>
63
+ <fieldset id="" class="scheme-list">
64
+ <?php foreach ( $this->fonts_processing_pro_options() as $name => $data ): ?>
65
+ <?php
66
+ $checked = defined( strtoupper( $name ) ) ? constant( strtoupper( $name ) ) : false;
67
+ $disabled = apply_filters( $name . '_setting_disabled', true ) ? 'disabled' : '';
68
+ ?>
69
+ <label for="<?= $name; ?>">
70
+ <input type="checkbox" name="<?= $name; ?>" <?= $checked ? 'checked="checked"' : ''; ?> <?= $disabled; ?> /><?= $data['label']; ?>
71
+ &nbsp;
72
+ </label>
73
+ <?php endforeach; ?>
74
+ </fieldset>
75
+ <p class="description">
76
+ <?= $this->promo; ?>
77
+ </p>
78
+ <ul>
79
+ <?php foreach ( $this->fonts_processing_pro_options() as $name => $data ): ?>
80
+ <li><strong><?= $data['label']; ?></strong>: <?= $data['description']; ?></li>
81
+ <?php endforeach; ?>
82
+ </ul>
83
+ </td>
84
+ </tr>
85
+ <?php
86
+ }
87
+
88
+ /**
89
+ * @return array
90
+ */
91
+ private function fonts_processing_pro_options () {
92
+ return [
93
+ 'omgf_pro_process_stylesheets' => [
94
+ 'label' => __( 'Process Stylesheets', $this->plugin_text_domain ),
95
+ 'description' => __( 'Process stylesheets loaded from <code>fonts.googleapis.com</code> or <code>fonts.gstatic.com</code>.', $this->plugin_text_domain )
96
+ ],
97
+ 'omgf_pro_process_inline_styles' => [
98
+ 'label' => __( 'Process Inline Styles', $this->plugin_text_domain ),
99
+ 'description' => __( 'Process all <code>@font-face</code> and <code>@import</code> rules loading Google Fonts.', $this->plugin_text_domain )
100
+ ],
101
+ 'omgf_pro_process_webfont_loader' => [
102
+ 'label' => __( 'Process Webfont Loader', $this->plugin_text_domain ),
103
+ 'description' => __( 'Process <code>webfont.js</code> libraries and the corresponding configuration defining which Google Fonts to load.', $this->plugin_text_domain )
104
+ ]
105
+ ];
106
+ }
107
+
108
+ /**
109
+ *
110
+ */
111
+ public function do_promo_advanced_processing () {
112
+ $this->do_checkbox(
113
+ __( 'Advanced Processing (Pro)', $this->plugin_text_domain ),
114
+ 'omgf_pro_advanced_processing',
115
+ defined( 'OMGF_PRO_ADVANCED_PROCESSING' ) ? true : false,
116
+ __( 'By default, OMGF scans for Google Fonts which are registered/enqueued in the <code>wp_enqueue_scripts()</code> action in WordPress\' header (<code>wp_head()</code>). Advanced Processing will process all Google Fonts throughout the entire document. This setting can be tweaked further under Advanced Settings.', $this->plugin_text_domain ) . ' ' . $this->promo,
117
+ true
118
+ );
119
+ }
120
+
121
+ /**
122
+ *
123
+ */
124
+ public function do_promo_process_resource_hints () {
125
+ $this->do_checkbox(
126
+ __( 'Remove Resource Hints (Pro)', $this->plugin_text_domain ),
127
+ 'omgf_pro_process_resource_hints',
128
+ defined( 'OMGF_PRO_PROCESS_RESOURCE_HINTS' ) ? OMGF_PRO_PROCESS_RESOURCE_HINTS : false,
129
+ __( 'Remove all <code>link</code> elements with a <code>rel</code> attribute value of <code>dns-prefetch</code>, <code>preload</code> or <code>preconnect</code> pointing to <code>fonts.googleapis.com</code> or <code>fonts.gstatic.com</code>.', $this->plugin_text_domain ) . ' ' . $this->promo,
130
+ true
131
+ );
132
+ }
133
+
134
+ /**
135
+ *
136
+ */
137
+ public function do_process_google_fonts () {
138
+ $this->do_select(
139
+ __( 'Google Fonts Processing', $this->plugin_text_domain ),
140
+ OMGF_Admin_Settings::OMGF_DETECTION_SETTING_FONT_PROCESSING,
141
+ OMGF_Admin_Settings::OMGF_FONT_PROCESSING_OPTIONS,
142
+ OMGF_FONT_PROCESSING,
143
+ sprintf( __( "Choose whether OMGF should (find, download and) <strong>replace</strong> all Google Fonts, or just <strong>remove</strong> them. Choosing Remove will force WordPress to fallback to system fonts.", $this->plugin_text_domain ), OMGF_Admin_Settings::FFWP_WORDPRESS_PLUGINS_OMGF_PRO )
144
+ );
145
+ }
146
+ }
includes/admin/settings/class-optimize.php ADDED
@@ -0,0 +1,304 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* * * * * * * * * * * * * * * * * * * * *
3
+ *
4
+ * ██████╗ ███╗ ███╗ ██████╗ ███████╗
5
+ * ██╔═══██╗████╗ ████║██╔════╝ ██╔════╝
6
+ * ██║ ██║██╔████╔██║██║ ███╗█████╗
7
+ * ██║ ██║██║╚██╔╝██║██║ ██║██╔══╝
8
+ * ╚██████╔╝██║ ╚═╝ ██║╚██████╔╝██║
9
+ * ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝
10
+ *
11
+ * @package : OMGF
12
+ * @author : Daan van den Bergh
13
+ * @copyright: (c) 2020 Daan van den Bergh
14
+ * @url : https://daan.dev
15
+ * * * * * * * * * * * * * * * * * * * */
16
+
17
+ defined( 'ABSPATH' ) || exit;
18
+
19
+ class OMGF_Admin_Settings_Optimize extends OMGF_Admin_Settings_Builder
20
+ {
21
+ /** @var array $optimized_fonts */
22
+ private $optimized_fonts;
23
+
24
+ /**
25
+ * OMGF_Admin_Settings_Optimize constructor.
26
+ */
27
+ public function __construct () {
28
+ parent::__construct();
29
+
30
+ $this->title = __( 'Optimize Google Fonts', $this->plugin_text_domain );
31
+
32
+ add_filter( 'omgf_optimize_settings_content', [ $this, 'do_title' ], 10 );
33
+ add_filter( 'omgf_optimize_settings_content', [ $this, 'do_description' ], 15 );
34
+
35
+ add_filter( 'omgf_optimize_settings_content', [ $this, 'do_before' ], 20 );
36
+ add_filter( 'omgf_optimize_settings_content', [ $this, 'do_optimization_mode' ], 30 );
37
+ add_filter( 'omgf_optimize_settings_content', [ $this, 'do_promo_combine_requests' ], 40 );
38
+ add_filter( 'omgf_optimize_settings_content', [ $this, 'do_display_option' ], 50 );
39
+ add_filter( 'omgf_optimize_settings_content', [ $this, 'do_promo_force_subsets' ], 60 );
40
+ add_filter( 'omgf_optimize_settings_content', [ $this, 'do_after' ], 100 );
41
+
42
+ add_filter( 'omgf_optimize_settings_content', [ $this, 'do_optimize_fonts_container' ], 200 );
43
+ add_filter( 'omgf_optimize_settings_content', [ $this, 'do_optimize_fonts_contents' ], 250 );
44
+ add_filter( 'omgf_optimize_settings_content', [ $this, 'close_optimize_fonts_container' ], 300 );
45
+
46
+ add_filter( 'omgf_optimize_settings_content', [ $this, 'do_before' ], 350 );
47
+ add_filter( 'omgf_optimize_settings_content', [ $this, 'do_optimize_edit_roles' ], 375 );
48
+ add_filter( 'omgf_optimize_settings_content', [ $this, 'do_after' ], 400 );
49
+ }
50
+
51
+ /**
52
+ *
53
+ */
54
+ public function do_description () {
55
+ ?>
56
+ <p>
57
+ <?= __( 'These settings affect the fonts OMGF downloads and the stylesheet it generates. If you\'re simply looking to replace your Google Fonts for locally hosted copies, the default settings should suffice.', $this->plugin_text_domain ); ?>
58
+ </p>
59
+ <?php
60
+ }
61
+
62
+ public function do_optimization_mode () {
63
+ $this->do_radio(
64
+ __( 'Optimization Mode', $this->plugin_text_domain ),
65
+ OMGF_Admin_Settings::OMGF_OPTIMIZATION_MODE,
66
+ OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_OPTIMIZATION_MODE,
67
+ OMGF_OPTIMIZATION_MODE,
68
+ __( '<strong>Manual</strong> processing mode is best suited for configurations, which use a fixed number of fonts across the entire site. <strong>Automatic</strong> processing mode is best suited for configurations using e.g. page builders, which load different fonts on certain pages.', $this->plugin_text_domain )
69
+ );
70
+ }
71
+
72
+ /**
73
+ *
74
+ */
75
+ public function do_promo_combine_requests () {
76
+ $this->do_checkbox(
77
+ __( 'Combine & Dedupe Google Fonts (Pro)', $this->plugin_text_domain ),
78
+ 'omgf_pro_combine_requests',
79
+ defined( 'OMGF_PRO_COMBINE_REQUESTS' ) ? true : false,
80
+ __( 'Combine and deduplicate multiple font requests into one request. This feature is always on in OMGF Pro.', $this->plugin_text_domain ) . ' ' . $this->promo,
81
+ true
82
+ );
83
+ }
84
+
85
+ /**
86
+ *
87
+ */
88
+ public function do_display_option () {
89
+ $this->do_select(
90
+ __( 'Font-display option', $this->plugin_text_domain ),
91
+ OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_DISPLAY_OPTION,
92
+ OMGF_Admin_Settings::OMGF_FONT_DISPLAY_OPTIONS,
93
+ OMGF_DISPLAY_OPTION,
94
+ __( 'Select which font-display strategy to use. Defaults to Swap (recommended).', $this->plugin_text_domain )
95
+ );
96
+ }
97
+
98
+ /**
99
+ *
100
+ */
101
+ public function do_promo_force_subsets () {
102
+ $this->do_select(
103
+ __( 'Force Subsets (Pro)', $this->plugin_text_domain ),
104
+ 'omgf_pro_force_subsets',
105
+ OMGF_Admin_Settings::OMGF_FORCE_SUBSETS_OPTIONS,
106
+ defined( 'OMGF_PRO_FORCE_SUBSETS' ) ? OMGF_PRO_FORCE_SUBSETS : [],
107
+ __( 'If a theme or plugin loads subsets you don\'t need, use this option to force all Google Fonts to be loaded in the selected subsets. You can also use this option to force the loading of additional subsets, if a theme/plugin doesn\'t allow you to configure the loaded subsets.', $this->plugin_text_domain ) . ' ' . $this->promo,
108
+ true,
109
+ true
110
+ );
111
+ }
112
+
113
+ /**
114
+ *
115
+ */
116
+ public function do_optimize_fonts_container () {
117
+ ?>
118
+ <div class="omgf-optimize-fonts-container welcome-panel">
119
+ <?php
120
+ }
121
+
122
+ /**
123
+ *
124
+ */
125
+ public function do_optimize_fonts_contents () {
126
+ $this->optimized_fonts = omgf_init()::optimized_fonts();
127
+ ?>
128
+ <h3><?= $this->optimized_fonts ? 'Manage Optimized Google Fonts' : __( 'Are you ready to Optimize your Google Fonts?', $this->plugin_text_domain ); ?></h3>
129
+ <?php if ( $this->optimized_fonts ): ?>
130
+ <?= $this->do_optimized_fonts_manager(); ?>
131
+ <?php else: ?>
132
+ <div class="omgf-optimize-fonts-description">
133
+ <?php
134
+ $this->do_manual_template();
135
+ $this->do_automatic_template();
136
+ ?>
137
+ </div>
138
+ <?php endif;
139
+ }
140
+
141
+ /**
142
+ *
143
+ */
144
+ private function do_optimized_fonts_manager () {
145
+ ?>
146
+ <?php if ( $this->optimized_fonts ): ?>
147
+ <div class="omgf-optimize-fonts-manage">
148
+ <p>
149
+
150
+ </p>
151
+ <table>
152
+ <thead>
153
+ <tr>
154
+ <td>&nbsp;</td>
155
+ <th><?= __( 'Style', $this->plugin_text_domain ); ?></th>
156
+ <th><?= __( 'Weight', $this->plugin_text_domain ); ?></th>
157
+ <th class="preload"><?= __( 'Preload', $this->plugin_text_domain ); ?></th>
158
+ <th class="unload"><?= __( 'Do not load', $this->plugin_text_domain ); ?></th>
159
+ </tr>
160
+ </thead>
161
+ <?php foreach ( $this->optimized_fonts as $handle => $fonts ): ?>
162
+ <tbody class="stylesheet" id="<?= $handle; ?>">
163
+ <?php foreach ( $fonts as $font ): ?>
164
+ <th><?= $font->family; ?> <span class="handle">(<?= $handle; ?>)</span></th>
165
+ <?php foreach ( $font->variants as $variant ): ?>
166
+ <tr>
167
+ <td></td>
168
+ <?php
169
+ $preload = get_option( OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_PRELOAD_FONTS )[ $handle ][ $font->id ][ $variant->id ] ?? '';
170
+ $unload = get_option( OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_UNLOAD_FONTS )[ $handle ][ $font->id ][ $variant->id ] ?? '';
171
+ ?>
172
+ <td><?= $variant->fontStyle; ?></td>
173
+ <td><?= $variant->fontWeight; ?></td>
174
+ <td>
175
+ <input autocomplete="off" type="checkbox" class="preload" name="<?= OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_PRELOAD_FONTS; ?>[<?= $handle; ?>][<?= $font->id; ?>][<?= $variant->id; ?>]" value="<?= $variant->id; ?>" <?= $preload ? 'checked="checked"' : ''; ?> />
176
+ </td>
177
+ <td>
178
+ <input autocomplete="off" type="checkbox" class="unload" name="<?= OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_UNLOAD_FONTS; ?>[<?= $handle; ?>][<?= $font->id; ?>][<?= $variant->id; ?>]" value="<?= $variant->id; ?>" <?= $unload ? 'checked="checked"' : ''; ?> />
179
+ </td>
180
+ </tr>
181
+ <?php endforeach; ?>
182
+ <?php endforeach; ?>
183
+ </tbody>
184
+ <?php endforeach; ?>
185
+ </table>
186
+ <div class="omgf-optimize-fonts-tooltip">
187
+ <p>
188
+ <span class="dashicons-before dashicons-info-outline"></span>
189
+ <?php if ( OMGF_OPTIMIZATION_MODE == 'manual' ): ?>
190
+ <em><?= sprintf( __( "This list is populated with all Google Fonts captured from <strong>%s</strong>. Optimizations will be applied on every page using these fonts. If you want to optimize additional Google Fonts from other pages, temporarily switch to <strong>Automatic</strong> and visit the pages containing the stylesheets you'd like to optimize. This list will automatically be populated with the captured fonts. When you feel the list is complete, switch back to <strong>Manual</strong>.", $this->plugin_text_domain ), OMGF_MANUAL_OPTIMIZE_URL ); ?></em>
191
+ <?php else: ?>
192
+ <?php
193
+ $no_cache_param = '?omgf_optimize=' . substr( md5( microtime() ), rand( 0, 26 ), 5 );
194
+ ?>
195
+ <em><?= sprintf( __( "This list is automatically populated with Google Fonts throughout your entire site. Optimizations will be applied on every page using these fonts. <strong>Automatic</strong> mode might not work when a Full Page Cache plugin is activated. If this list is not being populated with Google Fonts, you could try to visit your frontend and append the following parameter to the URL: <strong>%s</strong>", $this->plugin_text_domain ), $no_cache_param ); ?></em>
196
+ <?php endif; ?>
197
+ </p>
198
+ </div>
199
+ <input type="hidden" name="<?= OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_OPTIMIZED_FONTS; ?>" value="<?= serialize( $this->optimized_fonts ); ?>"/>
200
+ <input type="hidden" name="<?= OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_MANUAL_OPTIMIZE_URL; ?>" value="<?= OMGF_MANUAL_OPTIMIZE_URL; ?>"/>
201
+ <input id="<?= OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_UNLOAD_STYLESHEETS; ?>" type="hidden" name="<?= OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_UNLOAD_STYLESHEETS; ?>" value="<?= OMGF_UNLOAD_STYLESHEETS; ?>" />
202
+ </div>
203
+ <?php endif;
204
+ }
205
+
206
+ /**
207
+ *
208
+ */
209
+ public function do_manual_template () {
210
+ ?>
211
+ <div class="omgf-optimize-fonts-manual" <?= OMGF_OPTIMIZATION_MODE == 'manual' ? '' : 'style="display: none;"'; ?>>
212
+ <p>
213
+ <?= sprintf( __( "You've chosen to <strong>optimize your Google Fonts manually</strong>. OMGF will <u>not</u> run automatically and will <strong>%s</strong> the requested Google Fonts throughout your website that were captured on the post/page you defined. A Cross-Browser compatible stylesheet will be generated for all requested Google Fonts.", $this->plugin_text_domain ), OMGF_FONT_PROCESSING ); ?>
214
+ </p>
215
+ <div class="omgf-optimize-fonts-pros">
216
+ <h3>
217
+ <span class="dashicons-before dashicons-yes"></span> <?= __( 'Pros:', $this->plugin_text_domain ); ?>
218
+ </h3>
219
+ <ul>
220
+ <li><?= __( 'A small performance boost, because no calls to OMGF\'s Download API are made in the frontend.', $this->plugin_text_domain ); ?></li>
221
+ </ul>
222
+ </div>
223
+ <div class="omgf-optimize-fonts-cons">
224
+ <h3>
225
+ <span class="dashicons-before dashicons-no"></span> <?= __( 'Cons', $this->plugin_text_domain ); ?>
226
+ </h3>
227
+ <ul>
228
+ <li><?= __( 'High maintenance if you use a lot of different fonts on different pages.', $this->plugin_text_domain ); ?></li>
229
+ </ul>
230
+ </div>
231
+ <p>
232
+ <?= __( 'Enter the URL of the post/page you\'d like to scan for Google Fonts. The detected and optimized stylesheets will be applied on all pages where they\'re used.', $this->plugin_text_domain ); ?>
233
+ </p>
234
+ <label for="<?= OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_MANUAL_OPTIMIZE_URL; ?>">
235
+ <?= __( 'URL to Scan', $this->plugin_text_domain ); ?>
236
+ <input id="<?= OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_MANUAL_OPTIMIZE_URL; ?>" type="text"
237
+ name="<?= OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_MANUAL_OPTIMIZE_URL; ?>" value="<?= OMGF_MANUAL_OPTIMIZE_URL; ?>"/>
238
+ </label>
239
+ <div class="omgf-optimize-fonts-tooltip">
240
+ <p>
241
+ <span class="dashicons-before dashicons-info-outline"></span>
242
+ <em><?= __( 'This section will be populated with all captured fonts, font styles and available options after saving changes.', $this->plugin_text_domain ); ?></em>
243
+ </p>
244
+ </div>
245
+ </div>
246
+ <?php
247
+ }
248
+
249
+ /**
250
+ *
251
+ */
252
+ public function do_automatic_template () {
253
+ ?>
254
+ <div class="omgf-optimize-fonts-automatic" <?= OMGF_OPTIMIZATION_MODE == 'auto' ? '' : 'style="display: none;"'; ?>>
255
+ <p>
256
+ <?= sprintf( __( "You've chosen to <strong>optimize your Google Fonts automatically</strong>. OMGF will run silently in the background and <strong>%s</strong> all requested Google Fonts. If the captured stylesheet doesn't exist yet, a call is sent to OMGF's Download API to download the font files and generate a Cross-Browser compatible stylesheet.", $this->plugin_text_domain ), OMGF_FONT_PROCESSING ); ?>
257
+ </p>
258
+ <div class="omgf-optimize-fonts-pros">
259
+ <h3>
260
+ <span class="dashicons-before dashicons-yes"></span> <?= __( 'Pros:', $this->plugin_text_domain ); ?>
261
+ </h3>
262
+ <ul>
263
+ <li><?= __( 'No maintenance.', $this->plugin_text_domain ); ?></li>
264
+ </ul>
265
+ </div>
266
+ <div class="omgf-optimize-fonts-cons">
267
+ <h3>
268
+ <span class="dashicons-before dashicons-no"></span> <?= __( 'Cons', $this->plugin_text_domain ); ?>
269
+ </h3>
270
+ <ul>
271
+ <li><?= __( "Visitors might experience slow loading times, the 1st time they land on a page containing unoptimized Google Fonts. Every subsequent request to that page (and other pages using that same stylesheet) will be fast.", $this->plugin_text_domain ); ?></li>
272
+ </ul>
273
+ </div>
274
+ <div class="omgf-optimize-fonts-tooltip">
275
+ <p>
276
+ <span class="dashicons-before dashicons-info-outline"></span>
277
+ <em><?= __( "After saving your changes, this section will be populated with all captured fonts, font styles and available options as your site's frontend is visited by you or others. You will be able to manage your fonts at a later point.", $this->plugin_text_domain ); ?></em>
278
+ </p>
279
+ </div>
280
+ </div>
281
+ <?php
282
+ }
283
+
284
+ /**
285
+ *
286
+ */
287
+ public function close_optimize_fonts_container () {
288
+ ?>
289
+ </div>
290
+ <?php
291
+ }
292
+
293
+ /**
294
+ *
295
+ */
296
+ public function do_optimize_edit_roles () {
297
+ $this->do_checkbox(
298
+ __( 'Optimize fonts for logged in editors/administrators?', $this->plugin_text_domain ),
299
+ OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_OPTIMIZE_EDIT_ROLES,
300
+ OMGF_OPTIMIZE_EDIT_ROLES,
301
+ __( 'Should only be disabled while debugging/testing, e.g. using a page builder or switching themes.', $this->plugin_text_domain )
302
+ );
303
+ }
304
+ }
includes/api/class-download.php CHANGED
@@ -20,8 +20,10 @@ class OMGF_API_Download extends WP_REST_Controller
20
  {
21
  const OMGF_GOOGLE_FONTS_API_URL = 'https://google-webfonts-helper.herokuapp.com';
22
 
 
 
23
  /** @var array $endpoints */
24
- private $endpoints = [ 'css' ];
25
 
26
  /** @var string $namespace */
27
  protected $namespace = 'omgf/v1';
@@ -35,13 +37,6 @@ class OMGF_API_Download extends WP_REST_Controller
35
  /** @var string $path */
36
  private $path = '';
37
 
38
- /**
39
- * OMGF_API_Download constructor.
40
- */
41
- public function __construct () {
42
- add_filter( 'content_url', [ $this, 'rewrite_url' ], 10, 2 );
43
- }
44
-
45
  /**
46
  *
47
  */
@@ -70,54 +65,64 @@ class OMGF_API_Download extends WP_REST_Controller
70
  }
71
 
72
  /**
73
- * @param $request
74
  */
75
  public function process ( $request ) {
 
 
 
 
76
  $params = $request->get_params();
77
  $this->handle = $params['handle'] ?? '';
 
78
 
79
- if ( ! $this->handle ) {
80
  wp_send_json_error( 'Handle not provided.', 406 );
81
  }
82
 
83
- $this->path = WP_CONTENT_DIR . OMGF_CACHE_PATH . '/' . $this->handle;
84
-
85
  $url = self::OMGF_GOOGLE_FONTS_API_URL . '/api/fonts/%s';
86
  $font_families = explode( '|', $params['family'] );
87
 
 
 
 
 
 
 
 
 
88
  foreach ( $font_families as $font_family ) {
89
- list( $family, $variants ) = explode( ':', $font_family );
90
- $family = strtolower(str_replace( ' ', '-', $family ) );
 
 
 
 
 
 
91
 
92
- if ( defined( 'OMGF_PRO_FORCE_SUBSETS' ) && ! empty( OMGF_PRO_FORCE_SUBSETS ) ) {
93
- $query['subsets'] = implode( ',', OMGF_PRO_FORCE_SUBSETS );
94
- } else {
95
- $query['subsets'] = $params['subset'] ?? 'latin,latin-ext';
96
- }
97
 
98
- $response = wp_remote_get(
99
- sprintf( $url, $family ) . '?' . http_build_query( $query )
100
- );
101
 
102
- if ( ! is_wp_error( $response ) && wp_remote_retrieve_response_code( $response ) == 200 ) {
103
- $fonts[] = json_decode( wp_remote_retrieve_body( $response ) );
104
- }
105
- }
106
-
107
- foreach ( $fonts as &$font ) {
108
- $font_request = array_filter(
109
- $font_families,
110
- function ( $value ) use ( $font ) {
111
- return strpos( $value, $font->family ) !== false;
112
  }
113
- );
114
- $font->variants = $this->filter_variants( $font->variants, reset( $font_request ) );
 
115
  }
116
 
117
  foreach ( $fonts as &$font ) {
118
  foreach ( $font->variants as &$variant ) {
119
- $font_family = trim($variant->fontFamily, '\'"');
120
- $filename = strtolower( $font_family . '-' . $variant->fontStyle . '-' . $variant->fontWeight );
121
  $variant->woff = $this->download( $variant->woff, $filename );
122
  $variant->woff2 = $this->download( $variant->woff2, $filename );
123
  $variant->eot = $this->download( $variant->eot, $filename );
@@ -126,11 +131,20 @@ class OMGF_API_Download extends WP_REST_Controller
126
  }
127
 
128
  $stylesheet = $this->generate_stylesheet( $fonts );
129
-
130
  $local_file = $this->path . '/' . $this->handle . '.css';
131
 
132
  file_put_contents( $local_file, $stylesheet );
133
 
 
 
 
 
 
 
 
 
 
 
134
  // After downloading it, serve it.
135
  header( 'Content-Type: text/css' );
136
  header( "Content-Transfer-Encoding: Binary" );
@@ -140,6 +154,142 @@ class OMGF_API_Download extends WP_REST_Controller
140
  die();
141
  }
142
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
143
  /**
144
  * @param $available_variants
145
  * @param $wanted
@@ -160,8 +310,12 @@ class OMGF_API_Download extends WP_REST_Controller
160
  function ( $font ) use ( $variants ) {
161
  $id = $font->id;
162
 
163
- if ( $id == 'regular' || $id == 'italic' ) {
164
- $id = '400';
 
 
 
 
165
  }
166
 
167
  return in_array( $id, $variants );
@@ -170,9 +324,10 @@ class OMGF_API_Download extends WP_REST_Controller
170
  }
171
 
172
  /**
173
- * @param $urls
 
174
  *
175
- * @return bool
176
  */
177
  private function download ( $url, $filename ) {
178
  if ( ! function_exists( 'download_url' ) ) {
@@ -181,7 +336,7 @@ class OMGF_API_Download extends WP_REST_Controller
181
 
182
  wp_mkdir_p( $this->path );
183
 
184
- $file = $this->path . '/' . $filename . '.' . pathinfo($url, PATHINFO_EXTENSION);
185
  $file_uri = str_replace( WP_CONTENT_DIR, '', $file );
186
 
187
  if ( file_exists( $file ) ) {
@@ -195,40 +350,6 @@ class OMGF_API_Download extends WP_REST_Controller
195
  return content_url( $file_uri );
196
  }
197
 
198
- /**
199
- * @param $url
200
- * @param $path
201
- *
202
- * @return mixed
203
- */
204
- public function rewrite_url ( $url, $path ) {
205
- /**
206
- * Exit early if this isn't requested by OMGF.
207
- */
208
- if ( strpos( $url, OMGF_CACHE_PATH ) === false ) {
209
- return $url;
210
- }
211
-
212
- /**
213
- * If Relative URLs is enabled, overwrite URL with Path and continue execution.
214
- */
215
- if ( OMGF_RELATIVE_URL ) {
216
- $content_dir = str_replace( site_url(), '', content_url() );
217
-
218
- $url = $content_dir . $path;
219
- }
220
-
221
- if ( OMGF_CDN_URL ) {
222
- $url = str_replace( site_url(), OMGF_CDN_URL, $url );
223
- }
224
-
225
- if ( OMGF_CACHE_URI ) {
226
- $url = str_replace( OMGF_CACHE_PATH, OMGF_CACHE_URI, $url );
227
- }
228
-
229
- return $url;
230
- }
231
-
232
  /**
233
  * @param $fonts
234
  *
@@ -252,7 +373,7 @@ class OMGF_API_Download extends WP_REST_Controller
252
 
253
  $local_src = '';
254
 
255
- if (is_array($variant->local)) {
256
  foreach ( $variant->local as $local ) {
257
  $local_src .= "local('$local'), ";
258
  }
@@ -275,7 +396,7 @@ class OMGF_API_Download extends WP_REST_Controller
275
  /**
276
  * @param $sources
277
  * @param string $type
278
- * @param bool $endSemiColon
279
  *
280
  * @return string
281
  */
20
  {
21
  const OMGF_GOOGLE_FONTS_API_URL = 'https://google-webfonts-helper.herokuapp.com';
22
 
23
+ private $plugin_text_domain = 'host-webfonts-local';
24
+
25
  /** @var array $endpoints */
26
+ private $endpoints = [ 'css', 'css2' ];
27
 
28
  /** @var string $namespace */
29
  protected $namespace = 'omgf/v1';
37
  /** @var string $path */
38
  private $path = '';
39
 
 
 
 
 
 
 
 
40
  /**
41
  *
42
  */
65
  }
66
 
67
  /**
68
+ * @param $request WP_Rest_Request
69
  */
70
  public function process ( $request ) {
71
+ if ( strpos( $request->get_route(), 'css2' ) !== false ) {
72
+ $this->convert_css2( $request );
73
+ }
74
+
75
  $params = $request->get_params();
76
  $this->handle = $params['handle'] ?? '';
77
+ $original_handle = $request->get_param( 'original_handle' );
78
 
79
+ if ( ! $this->handle || ! $original_handle ) {
80
  wp_send_json_error( 'Handle not provided.', 406 );
81
  }
82
 
83
+ $this->path = WP_CONTENT_DIR . OMGF_CACHE_PATH . '/' . $this->handle;
 
84
  $url = self::OMGF_GOOGLE_FONTS_API_URL . '/api/fonts/%s';
85
  $font_families = explode( '|', $params['family'] );
86
 
87
+ if ( defined( 'OMGF_PRO_FORCE_SUBSETS' ) && ! empty( OMGF_PRO_FORCE_SUBSETS ) ) {
88
+ $query['subsets'] = implode( ',', OMGF_PRO_FORCE_SUBSETS );
89
+ } else {
90
+ $query['subsets'] = $params['subset'] ?? 'latin,latin-ext';
91
+ }
92
+
93
+ $fonts = [];
94
+
95
  foreach ( $font_families as $font_family ) {
96
+ $fonts[] = $this->grab_font_family( $font_family, $url, $query );
97
+ }
98
+
99
+ // Filter out empty element, i.e. failed requests.
100
+ $fonts = array_filter($fonts);
101
+
102
+ foreach ( $fonts as $font_key => &$font ) {
103
+ $font_request = $this->filter_font_families( $font_families, $font );
104
 
105
+ list ( $family, $variants ) = explode( ':', $font_request );
 
 
 
 
106
 
107
+ $variants = $this->process_variants( $variants, $font );
 
 
108
 
109
+ if ( $unloaded_fonts = omgf_init()::unloaded_fonts() ) {
110
+ $font_id = $font->id;
111
+
112
+ // Now we're sure we got 'em all. We can safely unload those we don't want.
113
+ if ( isset( $unloaded_fonts[ $original_handle ][ $font_id ] ) ) {
114
+ $variants = $this->dequeue_unloaded_fonts( $variants, $unloaded_fonts[ $original_handle ], $font->id );
115
+ $font_request = $family . ':' . implode( ',', $variants );
 
 
 
116
  }
117
+ }
118
+
119
+ $font->variants = $this->filter_variants( $font->variants, $font_request );
120
  }
121
 
122
  foreach ( $fonts as &$font ) {
123
  foreach ( $font->variants as &$variant ) {
124
+ $font_family = trim( $variant->fontFamily, '\'"' );
125
+ $filename = strtolower( str_replace( ' ', '-', $font_family ) . '-' . $variant->fontStyle . '-' . $variant->fontWeight );
126
  $variant->woff = $this->download( $variant->woff, $filename );
127
  $variant->woff2 = $this->download( $variant->woff2, $filename );
128
  $variant->eot = $this->download( $variant->eot, $filename );
131
  }
132
 
133
  $stylesheet = $this->generate_stylesheet( $fonts );
 
134
  $local_file = $this->path . '/' . $this->handle . '.css';
135
 
136
  file_put_contents( $local_file, $stylesheet );
137
 
138
+ $optimized_fonts = get_option( OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_OPTIMIZED_FONTS ) ?: [];
139
+ $current_font = [ $this->handle => $fonts ];
140
+
141
+ /**
142
+ * If handle was already detected before, there's no need of saving it to OMGF's options.
143
+ */
144
+ if ( ! isset( $optimized_fonts[ $original_handle ] ) ) {
145
+ update_option( OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_OPTIMIZED_FONTS, $optimized_fonts + $current_font );
146
+ }
147
+
148
  // After downloading it, serve it.
149
  header( 'Content-Type: text/css' );
150
  header( "Content-Transfer-Encoding: Binary" );
154
  die();
155
  }
156
 
157
+ /**
158
+ * @param $variants
159
+ * @param $unloaded_fonts
160
+ * @param $font_id
161
+ *
162
+ * @return array
163
+ */
164
+ private function dequeue_unloaded_fonts ( $variants, $unloaded_fonts, $font_id ) {
165
+ return array_filter(
166
+ $variants,
167
+ function ( $value ) use ( $unloaded_fonts, $font_id ) {
168
+ if ( $value == '400' ) {
169
+ // Sometimes the font is defined as 'regular', so we need to check both.
170
+ return ! in_array( 'regular', $unloaded_fonts [ $font_id ] ) && ! in_array( $value, $unloaded_fonts [ $font_id ] );
171
+ }
172
+
173
+ return ! in_array( $value, $unloaded_fonts[ $font_id ] );
174
+ }
175
+ );
176
+ }
177
+
178
+ /**
179
+ * Converts requests to OMGF's Download/CSS2 API to a format readable by the regular API.
180
+ *
181
+ * @param $request WP_Rest_Request
182
+ */
183
+ private function convert_css2 ( &$request ) {
184
+ $query = $this->get_query_from_request();
185
+ $params = explode( '&', $query );
186
+ $font_families = [];
187
+ $fonts = [];
188
+
189
+ foreach ( $params as $param ) {
190
+ if ( strpos( $param, 'family' ) === false ) {
191
+ continue;
192
+ }
193
+
194
+ parse_str( $param, $parts );
195
+
196
+ $font_families[] = $parts;
197
+ }
198
+
199
+ foreach ( $font_families as $font_family ) {
200
+ list( $family, $weights ) = explode( ':', reset( $font_family ) );
201
+
202
+ /**
203
+ * @return array [ '300', '400', '500', etc. ]
204
+ */
205
+ $weights = explode( ';', substr( $weights, strpos( $weights, '@' ) + 1 ) );
206
+
207
+ $fonts[] = $family . ':' . implode( ',', $weights );
208
+ }
209
+
210
+ $request->set_param( 'family', implode( '|', $fonts ) );
211
+ }
212
+
213
+ /**
214
+ * Since Google Fonts' variable fonts API uses the same name for each parameter ('family') we need to parse the url manually.
215
+ *
216
+ * @return mixed
217
+ */
218
+ private function get_query_from_request () {
219
+ return parse_url( $_SERVER['REQUEST_URI'] )['query'];
220
+ }
221
+
222
+ /**
223
+ * @param $font_family
224
+ * @param $url
225
+ * @param $query
226
+ *
227
+ * @return mixed|void
228
+ */
229
+ private function grab_font_family ( $font_family, $url, $query ) {
230
+ list( $family, $variants ) = explode( ':', $font_family );
231
+ $family = strtolower( str_replace( ' ', '-', $family ) );
232
+
233
+ $response = wp_remote_get(
234
+ sprintf( $url, $family ) . '?' . http_build_query( $query )
235
+ );
236
+
237
+ $response_code = $response['response']['code'] ?? '';
238
+
239
+ if ( $response_code !== 200) {
240
+ $message = sprintf( __( '<strong>%s</strong> could not be found using the current configuration. The API returned the following error: %s', $this->plugin_text_domain ), ucfirst( $family), wp_remote_retrieve_body( $response));
241
+
242
+ OMGF_Admin_Notice::set_notice(
243
+ $message,
244
+ 'omgf_api_error',
245
+ false,
246
+ 'error'
247
+ );
248
+
249
+ return [];
250
+ }
251
+
252
+ if ( ! is_wp_error( $response ) && wp_remote_retrieve_response_code( $response ) == 200 ) {
253
+ return json_decode( wp_remote_retrieve_body( $response ) );
254
+ }
255
+ }
256
+
257
+ /**
258
+ * @param $font_families
259
+ * @param $font
260
+ *
261
+ * @return mixed
262
+ */
263
+ private function filter_font_families ( $font_families, $font ) {
264
+ $font_request = array_filter(
265
+ $font_families,
266
+ function ( $value ) use ( $font ) {
267
+ return strpos( $value, $font->family ) !== false;
268
+ }
269
+ );
270
+
271
+ return reset( $font_request );
272
+ }
273
+
274
+ /**
275
+ * @param $variants
276
+ * @param $font
277
+ *
278
+ * @return array
279
+ */
280
+ private function process_variants ( $variants, $font ) {
281
+ $variants = array_filter( explode( ',', $variants ) );
282
+
283
+ // This means by default all fonts are requested, so we need to fill up the queue, before unloading the unwanted variants.
284
+ if ( count( $variants ) == 0 ) {
285
+ foreach ( $font->variants as $variant ) {
286
+ $variants[] = $variant->id;
287
+ }
288
+ }
289
+
290
+ return $variants;
291
+ }
292
+
293
  /**
294
  * @param $available_variants
295
  * @param $wanted
310
  function ( $font ) use ( $variants ) {
311
  $id = $font->id;
312
 
313
+ if ( $id == 'regular' || $id == '400' ) {
314
+ return in_array( '400', $variants ) || in_array( 'regular', $variants );
315
+ }
316
+
317
+ if ( $id == 'italic' ) {
318
+ return in_array( '400italic', $variants ) || in_array( 'italic', $variants );
319
  }
320
 
321
  return in_array( $id, $variants );
324
  }
325
 
326
  /**
327
+ * @param $url
328
+ * @param $filename
329
  *
330
+ * @return string
331
  */
332
  private function download ( $url, $filename ) {
333
  if ( ! function_exists( 'download_url' ) ) {
336
 
337
  wp_mkdir_p( $this->path );
338
 
339
+ $file = $this->path . '/' . $filename . '.' . pathinfo( $url, PATHINFO_EXTENSION );
340
  $file_uri = str_replace( WP_CONTENT_DIR, '', $file );
341
 
342
  if ( file_exists( $file ) ) {
350
  return content_url( $file_uri );
351
  }
352
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
353
  /**
354
  * @param $fonts
355
  *
373
 
374
  $local_src = '';
375
 
376
+ if ( is_array( $variant->local ) ) {
377
  foreach ( $variant->local as $local ) {
378
  $local_src .= "local('$local'), ";
379
  }
396
  /**
397
  * @param $sources
398
  * @param string $type
399
+ * @param bool $end_semi_colon
400
  *
401
  * @return string
402
  */
includes/class-admin.php CHANGED
@@ -37,7 +37,7 @@ class OMGF_Admin
37
  $this->show_notice = apply_filters(
38
  'omgf_admin_options_show_notice',
39
  [
40
- OMGF_Admin_Settings::OMGF_BASIC_SETTING_CACHE_PATH,
41
  OMGF_Admin_Settings::OMGF_ADV_SETTING_CACHE_URI,
42
  OMGF_Admin_Settings::OMGF_ADV_SETTING_RELATIVE_URL,
43
  OMGF_Admin_Settings::OMGF_ADV_SETTING_CDN_URL
@@ -47,10 +47,12 @@ class OMGF_Admin
47
  add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_admin_scripts' ] );
48
  add_action( 'admin_notices', [ $this, 'print_notices' ] );
49
 
50
- $this->do_basic_settings();
 
51
  $this->do_advanced_settings();
52
 
53
- add_action( 'admin_init', [ $this, 'maybe_show_optimize_notice' ] );
 
54
  add_filter( 'pre_update_option', [ $this, 'settings_changed' ], 10, 3 );
55
  }
56
 
@@ -81,10 +83,17 @@ class OMGF_Admin
81
  }
82
 
83
  /**
84
- * @return OMGF_Admin_Settings_Basic
85
  */
86
- private function do_basic_settings () {
87
- return new OMGF_Admin_Settings_Basic();
 
 
 
 
 
 
 
88
  }
89
 
90
  /**
@@ -95,42 +104,64 @@ class OMGF_Admin
95
  }
96
 
97
  /**
98
- * @param $new_value
99
- * @param $old_settings
 
100
  *
101
  * @return mixed
102
  */
103
- public function settings_changed ( $value, $option_name, $old_value ) {
104
- if ( ! in_array( $option_name, $this->show_notice ) ) {
 
 
 
 
 
 
 
 
 
 
 
105
  return $value;
106
  }
107
 
108
- if ( $value != $old_value ) {
109
- OMGF_Admin_Notice::set_notice(
110
- __( 'Settings changed. <a href="#" class="omgf-empty">Click here</a> to empty OMGF\'s cache.', $this->plugin_text_domain ),
111
- 'omgf-settings-changed',
112
- false
113
- );
 
 
 
 
114
  }
115
 
116
  return $value;
117
  }
118
 
119
  /**
 
 
120
  *
 
121
  */
122
- public function maybe_show_optimize_notice () {
123
- if ( get_option( OMGF_Admin_Settings::OMGF_OPTIMIZATION_COMPLETE ) ) {
124
- // If any notices were set in a previous run, unset them.
125
- OMGF_Admin_Notice::unset_notice( 'omgf-optimize' , 'success' );
 
 
 
126
 
127
- return;
 
 
 
 
128
  }
129
 
130
- OMGF_Admin_Notice::set_notice(
131
- __( 'OMGF is ready to optimize your Google Fonts. <a href="#" id="omgf-optimize">Start optimization</a>.', $this->plugin_text_domain ),
132
- 'omgf-optimize',
133
- false
134
- );
135
  }
136
  }
37
  $this->show_notice = apply_filters(
38
  'omgf_admin_options_show_notice',
39
  [
40
+ OMGF_Admin_Settings::OMGF_ADV_SETTING_CACHE_PATH,
41
  OMGF_Admin_Settings::OMGF_ADV_SETTING_CACHE_URI,
42
  OMGF_Admin_Settings::OMGF_ADV_SETTING_RELATIVE_URL,
43
  OMGF_Admin_Settings::OMGF_ADV_SETTING_CDN_URL
47
  add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_admin_scripts' ] );
48
  add_action( 'admin_notices', [ $this, 'print_notices' ] );
49
 
50
+ $this->do_optimize_settings();
51
+ $this->do_detection_settings();
52
  $this->do_advanced_settings();
53
 
54
+ add_filter( 'pre_update_option_omgf_optimized_fonts', [ $this, 'decode_option' ], 10, 3 );
55
+ add_filter( 'pre_update_option_omgf_unload_fonts', [ $this, 'clean_up_cache' ], 10, 3 );
56
  add_filter( 'pre_update_option', [ $this, 'settings_changed' ], 10, 3 );
57
  }
58
 
83
  }
84
 
85
  /**
86
+ * @return OMGF_Admin_Settings_Optimize
87
  */
88
+ private function do_optimize_settings () {
89
+ return new OMGF_Admin_Settings_Optimize();
90
+ }
91
+
92
+ /**
93
+ * @return OMGF_Admin_Settings_Detection
94
+ */
95
+ private function do_detection_settings () {
96
+ return new OMGF_Admin_Settings_Detection();
97
  }
98
 
99
  /**
104
  }
105
 
106
  /**
107
+ * @param $old_value
108
+ * @param $value
109
+ * @param $option_name
110
  *
111
  * @return mixed
112
  */
113
+ public function decode_option ( $old_value, $value, $option_name ) {
114
+ return $value;
115
+ }
116
+
117
+ /**
118
+ * Triggered when preload settings is changed, cleans up old cache files.
119
+ *
120
+ * @param $old_value
121
+ * @param $value
122
+ * @param $option_name
123
+ */
124
+ public function clean_up_cache ( $value, $old_value, $option_name ) {
125
+ if ( $value == $old_value ) {
126
  return $value;
127
  }
128
 
129
+ $uniq_id = '';
130
+
131
+ if ( omgf_init()::unloaded_fonts() ) {
132
+ $uniq_id = strlen( json_encode( $old_value ) );
133
+ }
134
+
135
+ $entries = array_filter( (array) glob( OMGF_FONTS_DIR . "/*$uniq_id" ) );
136
+
137
+ foreach ( $entries as $entry ) {
138
+ OMGF::delete( $entry );
139
  }
140
 
141
  return $value;
142
  }
143
 
144
  /**
145
+ * @param $new_value
146
+ * @param $old_settings
147
  *
148
+ * @return mixed
149
  */
150
+ public function settings_changed ( $value, $option_name, $old_value ) {
151
+ if ( ! in_array( $option_name, $this->show_notice ) ) {
152
+ return $value;
153
+ }
154
+
155
+ if ( $value != $old_value ) {
156
+ global $wp_settings_errors;
157
 
158
+ if ( ! empty ($wp_settings_errors ) ) {
159
+ $wp_settings_errors = [];
160
+ }
161
+
162
+ add_settings_error( 'general', 'omgf_settings_changed', __( 'Settings changed. <a href="#" class="omgf-empty">Click here</a> to empty OMGF\'s cache.', $this->plugin_text_domain ), 'success' );
163
  }
164
 
165
+ return $value;
 
 
 
 
166
  }
167
  }
includes/class-ajax.php CHANGED
@@ -26,7 +26,6 @@ class OMGF_AJAX
26
  */
27
  public function __construct () {
28
  add_action( 'wp_ajax_omgf_ajax_empty_dir', [ $this, 'empty_directory' ] );
29
- add_action( 'wp_ajax_omgf_ajax_optimize', [ $this, 'optimize' ] );
30
  }
31
 
32
  /**
@@ -37,10 +36,16 @@ class OMGF_AJAX
37
  $entries = array_filter( (array) glob( OMGF_FONTS_DIR . '/*' ) );
38
 
39
  foreach ( $entries as $entry ) {
40
- $this->delete( $entry );
41
  }
42
 
43
- update_option( OMGF_Admin_Settings::OMGF_OPTIMIZATION_COMPLETE, false );
 
 
 
 
 
 
44
 
45
  OMGF_Admin_Notice::set_notice( __( 'Cache directory successfully emptied.', $this->plugin_text_domain ) );
46
  } catch ( \Exception $e ) {
@@ -53,121 +58,4 @@ class OMGF_AJAX
53
  );
54
  }
55
  }
56
-
57
- /**
58
- * @param $entry
59
- */
60
- public function delete ( $entry ) {
61
- if ( is_dir( $entry ) ) {
62
- $file = new \FilesystemIterator( $entry );
63
-
64
- // If dir is empty, valid() returns false.
65
- while ( $file->valid() ) {
66
- $this->delete( $file->getPathName() );
67
- $file->next();
68
- }
69
-
70
- rmdir( $entry );
71
- } else {
72
- unlink( $entry );
73
- }
74
- }
75
-
76
- /**
77
- * Fetch Download API URLs from Frontend and go through them one by one, to trigger an uncached call to the Download API.
78
- */
79
- public function optimize () {
80
- $front_html = wp_remote_get(
81
- $this->no_cache( site_url() ),
82
- [
83
- 'timeout' => 30
84
- ]
85
- );
86
-
87
- if ( is_wp_error( $front_html ) ) {
88
- update_option( OMGF_Admin_Settings::OMGF_OPTIMIZATION_COMPLETE, false );
89
-
90
- OMGF_Admin_Notice::set_notice(
91
- __( 'OMGF encountered an error while fetching this site\'s frontend HTML', $this->plugin_text_domain ) . ': ' . $front_html->get_error_message(),
92
- 'omgf-fetch-failed',
93
- true,
94
- 'error',
95
- $front_html->get_error_code()
96
- );
97
- }
98
-
99
- $urls = [];
100
- $document = new DOMDocument();
101
- @$document->loadHtml( wp_remote_retrieve_body( $front_html ) );
102
-
103
- foreach ( $document->getElementsByTagName( 'link' ) as $link ) {
104
- /** @var $link DOMElement */
105
- if ( $link->hasAttribute( 'href' ) && strpos( $link->getAttribute( 'href' ), '/omgf/v1/download/css' ) ) {
106
- $urls[] = $link->getAttribute( 'href' );
107
- }
108
- }
109
-
110
- if ( empty( $urls ) ) {
111
- $message = __( 'No Google Fonts found to optimize. <a href="#" class="omgf-empty">Empty the Cache Directory</a> to start over.', $this->plugin_text_domain );
112
- $info = sprintf( __( 'If you believe this is an error, <a href="%s" target="_blank">click here</a> to trigger the optimization manually in your site\'s frontend.', $this->plugin_text_domain ), $this->no_cache( site_url() ) );
113
- $info .= ' ' . __( 'If this message keeps appearing,', $this->plugin_text_domain );
114
-
115
- if ( apply_filters( 'apply_omgf_pro_promo', true ) ) {
116
- $info .= ' ' . sprintf( __( 'head over to the Support Forum and <a target="_blank" href="%s">shoot me a ticket</a>.', $this->plugin_text_domain ), 'https://wordpress.org/support/plugin/host-webfonts-local/' );
117
- } else {
118
- $info .= ' ' . sprintf( __( '<a target="_blank" href="%s">send me a support ticket</a>.', $this->plugin_text_domain ), 'https://ffwp.dev/contact/' );
119
- }
120
-
121
- OMGF_Admin_Notice::unset_notice('omgf-optimize', 'success');
122
- OMGF_Admin_Notice::unset_notice('omgf-optimize-plugin-notice');
123
- OMGF_Admin_Notice::unset_notice('omgf-optimize-background');
124
-
125
- OMGF_Admin_Notice::set_notice(
126
- $message,
127
- 'omgf-fonts-not-found',
128
- false,
129
- 'error',
130
- 404
131
- );
132
-
133
- OMGF_Admin_Notice::set_notice(
134
- $info,
135
- 'omgf-support-info',
136
- true,
137
- 'info'
138
- );
139
- }
140
-
141
- foreach ( $urls as $url ) {
142
- $download = wp_remote_get(
143
- $this->no_cache( $url ),
144
- [
145
- 'timeout' => 30
146
- ]
147
- );
148
-
149
- if ( is_wp_error( $download ) ) {
150
- update_option( OMGF_Admin_Settings::OMGF_OPTIMIZATION_COMPLETE, false );
151
-
152
- OMGF_Admin_Notice::set_notice(
153
- __( 'OMGF encountered an error while downloading Google Fonts', $this->plugin_text_domain ) . ': ' . $download->get_error_message(),
154
- 'omgf-download-failed',
155
- true,
156
- 'error',
157
- $download->get_error_code()
158
- );
159
- }
160
- }
161
-
162
- update_option( OMGF_Admin_Settings::OMGF_OPTIMIZATION_COMPLETE, true );
163
- }
164
-
165
- /**
166
- * @param $url
167
- *
168
- * @return string
169
- */
170
- private function no_cache ( $url ) {
171
- return add_query_arg( [ 'nocache' => substr( md5( microtime() ), rand( 0, 26 ), 5 ) ], $url );
172
- }
173
  }
26
  */
27
  public function __construct () {
28
  add_action( 'wp_ajax_omgf_ajax_empty_dir', [ $this, 'empty_directory' ] );
 
29
  }
30
 
31
  /**
36
  $entries = array_filter( (array) glob( OMGF_FONTS_DIR . '/*' ) );
37
 
38
  foreach ( $entries as $entry ) {
39
+ OMGF::delete( $entry );
40
  }
41
 
42
+ /**
43
+ * Empty related options.
44
+ */
45
+ delete_option( OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_OPTIMIZED_FONTS );
46
+ delete_option( OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_UNLOAD_FONTS );
47
+ delete_option( OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_PRELOAD_FONTS );
48
+ delete_option( OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_UNLOAD_STYLESHEETS );
49
 
50
  OMGF_Admin_Notice::set_notice( __( 'Cache directory successfully emptied.', $this->plugin_text_domain ) );
51
  } catch ( \Exception $e ) {
58
  );
59
  }
60
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  }
includes/class-omgf.php CHANGED
@@ -18,8 +18,6 @@ defined( 'ABSPATH' ) || exit;
18
 
19
  class OMGF
20
  {
21
- private $plugin_text_domain = 'host-webfonts-local';
22
-
23
  /**
24
  * OMGF constructor.
25
  */
@@ -36,6 +34,7 @@ class OMGF
36
  }
37
 
38
  add_action( 'rest_api_init', [ $this, 'register_routes' ] );
 
39
  }
40
 
41
  /**
@@ -43,15 +42,64 @@ class OMGF
43
  */
44
  public function define_constants () {
45
  define( 'OMGF_SITE_URL', 'https://daan.dev' );
46
- define( 'OMGF_FONT_PROCESSING', esc_attr( get_option( OMGF_Admin_Settings::OMGF_BASIC_SETTING_FONT_PROCESSING, 'replace' ) ) );
47
- define( 'OMGF_DISPLAY_OPTION', esc_attr( get_option( OMGF_Admin_Settings::OMGF_BASIC_SETTING_DISPLAY_OPTION, 'swap' ) ) ?: 'swap' );
48
- define( 'OMGF_OPTIMIZE_EDIT_ROLES', esc_attr( get_option( OMGF_Admin_Settings::OMGF_BASIC_SETTING_OPTIMIZE_EDIT_ROLES, 'on' ) ) );
49
- define( 'OMGF_CACHE_PATH', esc_attr( get_option( OMGF_Admin_Settings::OMGF_BASIC_SETTING_CACHE_PATH ) ) ?: '/uploads/omgf' );
 
 
50
  define( 'OMGF_CACHE_URI', esc_attr( get_option( OMGF_Admin_Settings::OMGF_ADV_SETTING_CACHE_URI ) ) ?: '' );
51
  define( 'OMGF_RELATIVE_URL', esc_attr( get_option( OMGF_Admin_Settings::OMGF_ADV_SETTING_RELATIVE_URL ) ) );
52
  define( 'OMGF_CDN_URL', esc_attr( get_option( OMGF_Admin_Settings::OMGF_ADV_SETTING_CDN_URL ) ) );
53
  define( 'OMGF_FONTS_DIR', WP_CONTENT_DIR . OMGF_CACHE_PATH );
54
  define( 'OMGF_UNINSTALL', esc_attr( get_option( OMGF_Admin_Settings::OMGF_ADV_SETTING_UNINSTALL ) ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
  }
56
 
57
  /**
@@ -83,6 +131,13 @@ class OMGF
83
  $proxy->register_routes();
84
  }
85
 
 
 
 
 
 
 
 
86
  /**
87
  * @return OMGF_Uninstall
88
  * @throws ReflectionException
@@ -90,4 +145,23 @@ class OMGF
90
  public static function do_uninstall () {
91
  return new OMGF_Uninstall();
92
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93
  }
18
 
19
  class OMGF
20
  {
 
 
21
  /**
22
  * OMGF constructor.
23
  */
34
  }
35
 
36
  add_action( 'rest_api_init', [ $this, 'register_routes' ] );
37
+ add_action( 'admin_init', [ $this, 'do_optimize' ] );
38
  }
39
 
40
  /**
42
  */
43
  public function define_constants () {
44
  define( 'OMGF_SITE_URL', 'https://daan.dev' );
45
+ define( 'OMGF_OPTIMIZATION_MODE', esc_attr( get_option( OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_OPTIMIZATION_MODE, 'manual' ) ) );
46
+ define( 'OMGF_MANUAL_OPTIMIZE_URL', esc_attr( get_option( OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_MANUAL_OPTIMIZE_URL, site_url() ) ) );
47
+ define( 'OMGF_FONT_PROCESSING', esc_attr( get_option( OMGF_Admin_Settings::OMGF_DETECTION_SETTING_FONT_PROCESSING, 'replace' ) ) );
48
+ define( 'OMGF_DISPLAY_OPTION', esc_attr( get_option( OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_DISPLAY_OPTION, 'swap' ) ) ?: 'swap' );
49
+ define( 'OMGF_OPTIMIZE_EDIT_ROLES', esc_attr( get_option( OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_OPTIMIZE_EDIT_ROLES, 'on' ) ) );
50
+ define( 'OMGF_CACHE_PATH', esc_attr( get_option( OMGF_Admin_Settings::OMGF_ADV_SETTING_CACHE_PATH ) ) ?: '/uploads/omgf' );
51
  define( 'OMGF_CACHE_URI', esc_attr( get_option( OMGF_Admin_Settings::OMGF_ADV_SETTING_CACHE_URI ) ) ?: '' );
52
  define( 'OMGF_RELATIVE_URL', esc_attr( get_option( OMGF_Admin_Settings::OMGF_ADV_SETTING_RELATIVE_URL ) ) );
53
  define( 'OMGF_CDN_URL', esc_attr( get_option( OMGF_Admin_Settings::OMGF_ADV_SETTING_CDN_URL ) ) );
54
  define( 'OMGF_FONTS_DIR', WP_CONTENT_DIR . OMGF_CACHE_PATH );
55
  define( 'OMGF_UNINSTALL', esc_attr( get_option( OMGF_Admin_Settings::OMGF_ADV_SETTING_UNINSTALL ) ) );
56
+ define( 'OMGF_UNLOAD_STYLESHEETS', esc_attr( get_option( OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_UNLOAD_STYLESHEETS, '' ) ) );
57
+ }
58
+
59
+ /**
60
+ * @return array
61
+ */
62
+ public static function optimized_fonts () {
63
+ static $optimized_fonts = null;
64
+
65
+ if ( $optimized_fonts === null ) {
66
+ $optimized_fonts = get_option( OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_OPTIMIZED_FONTS, [] );
67
+ }
68
+
69
+ return $optimized_fonts;
70
+ }
71
+
72
+ /**
73
+ * @return array
74
+ */
75
+ public static function unloaded_fonts () {
76
+ static $unloaded_fonts = null;
77
+
78
+ if ( $unloaded_fonts === null ) {
79
+ $unloaded_fonts = get_option( OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_UNLOAD_FONTS, [] );
80
+ }
81
+
82
+ return $unloaded_fonts;
83
+ }
84
+
85
+ /**
86
+ * @return array
87
+ */
88
+ public static function unloaded_stylesheets () {
89
+ static $unloaded_stylesheets = null;
90
+
91
+ if ( $unloaded_stylesheets === null ) {
92
+ $unloaded_stylesheets = explode( ',', get_option( OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_UNLOAD_STYLESHEETS, '' ) );
93
+ }
94
+
95
+ return array_filter( $unloaded_stylesheets );
96
+ }
97
+
98
+ /**
99
+ * @return array
100
+ */
101
+ public static function preloaded_fonts () {
102
+ return get_option( OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_PRELOAD_FONTS, [] );
103
  }
104
 
105
  /**
131
  $proxy->register_routes();
132
  }
133
 
134
+ /**
135
+ * @return OMGF_Optimize
136
+ */
137
+ public function do_optimize () {
138
+ return new OMGF_Optimize();
139
+ }
140
+
141
  /**
142
  * @return OMGF_Uninstall
143
  * @throws ReflectionException
145
  public static function do_uninstall () {
146
  return new OMGF_Uninstall();
147
  }
148
+
149
+ /**
150
+ * @param $entry
151
+ */
152
+ public static function delete ( $entry ) {
153
+ if ( is_dir( $entry ) ) {
154
+ $file = new \FilesystemIterator( $entry );
155
+
156
+ // If dir is empty, valid() returns false.
157
+ while ( $file->valid() ) {
158
+ self::delete( $file->getPathName() );
159
+ $file->next();
160
+ }
161
+
162
+ rmdir( $entry );
163
+ } else {
164
+ unlink( $entry );
165
+ }
166
+ }
167
  }
includes/class-optimize.php ADDED
@@ -0,0 +1,150 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* * * * * * * * * * * * * * * * * * * * *
3
+ *
4
+ * ██████╗ ███╗ ███╗ ██████╗ ███████╗
5
+ * ██╔═══██╗████╗ ████║██╔════╝ ██╔════╝
6
+ * ██║ ██║██╔████╔██║██║ ███╗█████╗
7
+ * ██║ ██║██║╚██╔╝██║██║ ██║██╔══╝
8
+ * ╚██████╔╝██║ ╚═╝ ██║╚██████╔╝██║
9
+ * ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝
10
+ *
11
+ * @package : OMGF
12
+ * @author : Daan van den Bergh
13
+ * @copyright: (c) 2020 Daan van den Bergh
14
+ * @url : https://daan.dev
15
+ * * * * * * * * * * * * * * * * * * * */
16
+
17
+ defined( 'ABSPATH' ) || exit;
18
+
19
+ class OMGF_Optimize
20
+ {
21
+ /** @var string $plugin_text_domain */
22
+ private $plugin_text_domain = 'host-webfonts-local';
23
+
24
+ /** @var mixed|string $optimization_mode */
25
+ private $optimization_mode = '';
26
+
27
+ /**
28
+ * OMGF_Optimize constructor.
29
+ */
30
+ public function __construct () {
31
+ $option_page = $_POST['option_page'] ?? '';
32
+ $this->optimization_mode = $_POST[ OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_OPTIMIZATION_MODE ] ?? '';
33
+
34
+ if ( $option_page != OMGF_Admin_Settings::OMGF_SETTINGS_FIELD_OPTIMIZE
35
+ && ! $this->optimization_mode ) {
36
+ return;
37
+ }
38
+
39
+ // Will die when it fails.
40
+ check_admin_referer( 'omgf-optimize-settings-options' );
41
+
42
+ update_option( OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_UNLOAD_FONTS, $_POST[ OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_UNLOAD_FONTS ] );
43
+ update_option( OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_PRELOAD_FONTS, $_POST[ OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_PRELOAD_FONTS ] );
44
+ update_option( OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_UNLOAD_STYLESHEETS, $_POST[ OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_UNLOAD_STYLESHEETS ] );
45
+
46
+ if ( $this->optimization_mode == 'manual' ) {
47
+ $this->run_manual();
48
+ }
49
+
50
+ if ( $this->optimization_mode == 'auto' ) {
51
+ $this->run_auto();
52
+ }
53
+ }
54
+
55
+ /**
56
+ *
57
+ */
58
+ private function run_manual () {
59
+ $url = esc_url_raw( $_POST[ OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_MANUAL_OPTIMIZE_URL ] );
60
+
61
+ $front_html = wp_remote_get(
62
+ $this->no_cache_optimize_url( $url ),
63
+ [
64
+ 'timeout' => 30
65
+ ]
66
+ );
67
+
68
+ if ( is_wp_error( $front_html ) ) {
69
+ $this->frontend_fetch_failed( $front_html );
70
+ }
71
+
72
+ $urls = [];
73
+ $document = new DOMDocument();
74
+ @$document->loadHtml( wp_remote_retrieve_body( $front_html ) );
75
+
76
+ foreach ( $document->getElementsByTagName( 'link' ) as $link ) {
77
+ /** @var $link DOMElement */
78
+ if ( $link->hasAttribute( 'href' ) && strpos( $link->getAttribute( 'href' ), '/omgf/v1/download/' ) ) {
79
+ $urls[] = $link->getAttribute( 'href' );
80
+ }
81
+ }
82
+
83
+ if ( empty( $urls ) ) {
84
+ $this->no_urls_found();
85
+ }
86
+
87
+ foreach ( $urls as $url ) {
88
+ $download = wp_remote_get(
89
+ $this->no_cache_optimize_url( $url ),
90
+ [
91
+ 'timeout' => 30
92
+ ]
93
+ );
94
+
95
+ if ( is_wp_error( $download ) ) {
96
+ $this->download_failed( $download );
97
+ }
98
+ }
99
+
100
+ $this->optimization_succeeded();
101
+ }
102
+
103
+ /**
104
+ *
105
+ */
106
+ private function optimization_succeeded () {
107
+ add_settings_error( 'general', 'omgf_optimization_success', __( 'Optimization completed successfully.' ), 'success' );
108
+ }
109
+
110
+ /**
111
+ * @param $download WP_Error
112
+ */
113
+ private function download_failed ( $download ) {
114
+ add_settings_error( 'general', 'omgf_download_failed', __( 'OMGF encountered an error while downloading Google Fonts', $this->plugin_text_domain ) . ': ' . $download->get_error_code() . ' - ' . $download->get_error_message(), 'error' );
115
+ }
116
+
117
+ /**
118
+ * @param $front_html WP_Error
119
+ */
120
+ private function frontend_fetch_failed ( $front_html ) {
121
+ add_settings_error( 'general', 'omgf_frontend_fetch_failed', __( 'OMGF encountered an error while fetching this site\'s frontend HTML', $this->plugin_text_domain ) . ': ' . $front_html->get_error_code() . ' - ' . $front_html->get_error_message(), 'error' );
122
+ }
123
+
124
+ /**
125
+ *
126
+ */
127
+ private function no_urls_found () {
128
+ add_settings_error( 'general', 'omgf_no_urls_found', __( 'No (additional) Google Fonts found to optimize.', $this->plugin_text_domain ), 'info' );
129
+ }
130
+
131
+ /**
132
+ *
133
+ */
134
+ private function run_auto () {
135
+ OMGF_Admin_Notice::set_notice(
136
+ __( 'OMGF Optimization is silently running in the background. After visiting a few pages, return here to manage the captured Google Fonts.' ),
137
+ 'omgf-auto-running',
138
+ false
139
+ );
140
+ }
141
+
142
+ /**
143
+ * @param $url
144
+ *
145
+ * @return string
146
+ */
147
+ private function no_cache_optimize_url ( $url ) {
148
+ return add_query_arg( [ 'omgf_optimize' => 1, 'nocache' => substr( md5( microtime() ), rand( 0, 26 ), 5 ) ], $url );
149
+ }
150
+ }
includes/frontend/class-functions.php CHANGED
@@ -29,6 +29,8 @@ class OMGF_Frontend_Functions
29
  public function __construct () {
30
  $this->do_optimize = $this->maybe_optimize_fonts();
31
 
 
 
32
  add_action( 'wp_print_styles', [ $this, 'process_fonts' ], PHP_INT_MAX - 1000 );
33
  }
34
 
@@ -45,6 +47,75 @@ class OMGF_Frontend_Functions
45
  return true;
46
  }
47
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
  /**
49
  * Check if the Remove Google Fonts option is enabled.
50
  */
@@ -82,8 +153,6 @@ class OMGF_Frontend_Functions
82
  foreach ( $fonts as $handle => $font ) {
83
  $wp_styles->registered [ $handle ]->src = '';
84
  }
85
-
86
- $this->maybe_show_optimization_finished_notice();
87
  }
88
 
89
  /**
@@ -92,11 +161,25 @@ class OMGF_Frontend_Functions
92
  public function replace_registered_fonts () {
93
  global $wp_styles;
94
 
95
- $registered = $wp_styles->registered;
96
- $fonts = apply_filters( 'omgf_auto_replace', $this->detect_registered_google_fonts( $registered ) );
 
97
 
98
  foreach ( $fonts as $handle => $font ) {
99
- $cached_file = OMGF_CACHE_PATH . '/' . $handle . "/$handle.css";
 
 
 
 
 
 
 
 
 
 
 
 
 
100
 
101
  if ( file_exists( WP_CONTENT_DIR . $cached_file ) ) {
102
  $wp_styles->registered[ $handle ]->src = content_url( $cached_file );
@@ -104,20 +187,9 @@ class OMGF_Frontend_Functions
104
  continue;
105
  }
106
 
107
- $wp_styles->registered[ $handle ]->src = str_replace( [ 'https://fonts.googleapis.com/', '//fonts.googleapis.com/' ], site_url( '/wp-json/omgf/v1/download/' ), $font->src ) . "&handle=$handle";
108
- }
109
-
110
- $this->maybe_show_optimization_finished_notice();
111
- }
112
-
113
- /**
114
- *
115
- */
116
- private function maybe_show_optimization_finished_notice () {
117
- if ( ! get_option( OMGF_Admin_Settings::OMGF_OPTIMIZATION_COMPLETE ) ) {
118
- update_option( OMGF_Admin_Settings::OMGF_OPTIMIZATION_COMPLETE, true );
119
-
120
- OMGF_Admin_Notice::optimization_finished();
121
  }
122
  }
123
 
29
  public function __construct () {
30
  $this->do_optimize = $this->maybe_optimize_fonts();
31
 
32
+ add_filter( 'content_url', [ $this, 'rewrite_url' ], 10, 2 );
33
+ add_action( 'wp_head', [ $this, 'add_preloads' ], 3 );
34
  add_action( 'wp_print_styles', [ $this, 'process_fonts' ], PHP_INT_MAX - 1000 );
35
  }
36
 
47
  return true;
48
  }
49
 
50
+ /**
51
+ * @param $url
52
+ * @param $path
53
+ *
54
+ * @return mixed
55
+ */
56
+ public function rewrite_url ( $url, $path ) {
57
+ /**
58
+ * Exit early if this isn't requested by OMGF.
59
+ */
60
+ if ( strpos( $url, OMGF_CACHE_PATH ) === false ) {
61
+ return $url;
62
+ }
63
+
64
+ /**
65
+ * If Relative URLs is enabled, overwrite URL with Path and continue execution.
66
+ */
67
+ if ( OMGF_RELATIVE_URL ) {
68
+ $content_dir = str_replace( site_url(), '', content_url() );
69
+
70
+ $url = $content_dir . $path;
71
+ }
72
+
73
+ if ( OMGF_CDN_URL ) {
74
+ $url = str_replace( site_url(), OMGF_CDN_URL, $url );
75
+ }
76
+
77
+ if ( OMGF_CACHE_URI ) {
78
+ $url = str_replace( OMGF_CACHE_PATH, OMGF_CACHE_URI, $url );
79
+ }
80
+
81
+ return $url;
82
+ }
83
+
84
+ /**
85
+ *
86
+ */
87
+ public function add_preloads () {
88
+ $preloaded_fonts = omgf_init()::preloaded_fonts();
89
+
90
+ if ( ! $preloaded_fonts ) {
91
+ return;
92
+ }
93
+
94
+ $stylesheets = omgf_init()::optimized_fonts();
95
+
96
+ foreach ( $stylesheets as $stylesheet => $fonts ) {
97
+ foreach ( $fonts as $font ) {
98
+ if ( ! in_array( $font->id, array_keys( $preloaded_fonts [ $stylesheet ] ) ) ) {
99
+ continue;
100
+ }
101
+
102
+ $font_id = $font->id;
103
+ $preloads_stylesheet = $preloaded_fonts [ $stylesheet ];
104
+ $preload_variants = array_filter(
105
+ $font->variants,
106
+ function ( $variant ) use ( $preloads_stylesheet, $font_id ) {
107
+ return in_array( $variant->id, $preloads_stylesheet[ $font_id ] );
108
+ }
109
+ );
110
+
111
+ foreach ( $preload_variants as $variant ) {
112
+ $url = $variant->woff2;
113
+ echo "<link id='omgf-preload' rel='preload' href='$url' />\n";
114
+ }
115
+ }
116
+ }
117
+ }
118
+
119
  /**
120
  * Check if the Remove Google Fonts option is enabled.
121
  */
153
  foreach ( $fonts as $handle => $font ) {
154
  $wp_styles->registered [ $handle ]->src = '';
155
  }
 
 
156
  }
157
 
158
  /**
161
  public function replace_registered_fonts () {
162
  global $wp_styles;
163
 
164
+ $registered = $wp_styles->registered;
165
+ $fonts = apply_filters( 'omgf_auto_replace', $this->detect_registered_google_fonts( $registered ) );
166
+ $unloaded_stylesheets = omgf_init()::unloaded_stylesheets();
167
 
168
  foreach ( $fonts as $handle => $font ) {
169
+ // If this stylesheet has been marked for unload, empty the src and skip out early.
170
+ if ( in_array( $handle, $unloaded_stylesheets ) ) {
171
+ $wp_styles->registered[ $handle ]->src = '';
172
+
173
+ continue;
174
+ }
175
+
176
+ $updated_handle = $handle;
177
+
178
+ if ( $unloaded_fonts = omgf_init()::unloaded_fonts() ) {
179
+ $updated_handle = $handle . '-' . strlen( json_encode( $unloaded_fonts ) );
180
+ }
181
+
182
+ $cached_file = OMGF_CACHE_PATH . '/' . $updated_handle . "/$updated_handle.css";
183
 
184
  if ( file_exists( WP_CONTENT_DIR . $cached_file ) ) {
185
  $wp_styles->registered[ $handle ]->src = content_url( $cached_file );
187
  continue;
188
  }
189
 
190
+ if ( OMGF_OPTIMIZATION_MODE == 'auto' || ( OMGF_OPTIMIZATION_MODE == 'manual' && isset( $_GET['omgf_optimize'] ) ) ) {
191
+ $wp_styles->registered[ $handle ]->src = str_replace( [ 'https://fonts.googleapis.com/', '//fonts.googleapis.com/' ], site_url( '/wp-json/omgf/v1/download/' ), $font->src ) . "&handle=$updated_handle&original_handle=$handle";
192
+ }
 
 
 
 
 
 
 
 
 
 
 
193
  }
194
  }
195
 
readme.md CHANGED
@@ -22,6 +22,9 @@ Please keep in mind that, although I try to make the configuration of this plugi
22
  ### Features
23
  - Automatically replace registered/enqueued Google Fonts in `wp_head()` with local copies,
24
  - Automatically remove registered/enqueued Google Fonts from `wp_head()`,
 
 
 
25
  - Leverage the font-display (swap) option,
26
  - Serve fonts from CDN,
27
  - Use OMGF with *security through obscurity* plugins.
@@ -34,7 +37,7 @@ Everything in the free version, plus:
34
  - Reduce loading time and page size, by forcing the used subset(s) for all Google Fonts requests,
35
  - Remove Resource Hints (preload, preconnect, dns-prefetch) pointing to fonts.googleapis.com or fonts.gstatic.com.
36
 
37
- *Click [here](https://ffwp.dev/wordpress/omgf-pro/) for more information and to purchase OMGF Pro.*
38
 
39
 
40
  ## Installation
22
  ### Features
23
  - Automatically replace registered/enqueued Google Fonts in `wp_head()` with local copies,
24
  - Automatically remove registered/enqueued Google Fonts from `wp_head()`,
25
+ - Manage Optimized Google Fonts,
26
+ - Preload above the fold fonts,
27
+ - Don't load certain fonts or entire stylesheets.
28
  - Leverage the font-display (swap) option,
29
  - Serve fonts from CDN,
30
  - Use OMGF with *security through obscurity* plugins.
37
  - Reduce loading time and page size, by forcing the used subset(s) for all Google Fonts requests,
38
  - Remove Resource Hints (preload, preconnect, dns-prefetch) pointing to fonts.googleapis.com or fonts.gstatic.com.
39
 
40
+ **[Documentation](https://ffwp.dev/docs/omgf-pro/) | [Purchase OMGF Pro](https://ffwp.dev/wordpress/omgf-pro/)**
41
 
42
 
43
  ## Installation
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: DaanvandenBergh
3
  Tags: google, fonts, gdpr, cache, speed, preload, font-display, webfonts, subsets, remove, minimize, external, requests
4
  Requires at least: 4.6
5
  Tested up to: 5.5
6
- Stable tag: 4.1.3
7
  Requires PHP: 7.0
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
@@ -21,15 +21,22 @@ OMGF is written with performance and user-friendliness in mind. It uses the Goog
21
 
22
  = How Does It Work? =
23
 
24
- After installing the plugin, OMGF runs silently in the background and captures any requests made to fonts.googleapis.com or fonts.gstatic.com. When a webpage is first loaded, it reroutes these requests to its own Download API and copies the fonts over to your server. Then it generates a stylesheet for your fonts including EOT, TTF, WOFF and WOFF2 formats to guarantee maximum cross browser compatibility!
25
 
26
- When the fonts are downloaded and the stylesheet is generated, it rewrites every URL pointing to fonts.googleapis.com or fonts.gstatic.com to the locally hosted variant.
 
 
 
 
27
 
28
  Please keep in mind that, although I try to make the configuration of this plugin as easy as possible, the concept of locally hosting a file or optimizing Google Fonts for *Pagespeed Insights* or *GT Metrix* has proven to be confusing for some people. If you're not sure of what your doing, please consult a SEO expert or Webdeveloper to help you with the configuration of this plugin or [hire me to do it for you](https://ffwp.dev/wordpress/omgf-expert-configuration/).
29
 
30
  = Features =
31
  - Automatically replace registered/enqueued Google Fonts in wp_head() with local copies,
32
  - Automatically remove registered/enqueued Google Fonts from wp_head(),
 
 
 
33
  - Leverage the font-display (swap) option,
34
  - Serve fonts from CDN,
35
  - Use OMGF with *security through obscurity* plugins.
@@ -42,7 +49,7 @@ Everything in the free version, plus:
42
  - Reduce loading time and page size, by forcing the used subset(s) for all Google Fonts requests,
43
  - Remove Resource Hints (preload, preconnect, dns-prefetch) pointing to fonts.googleapis.com or fonts.gstatic.com.
44
 
45
- *Click [here](https://ffwp.dev/wordpress/omgf-pro/) for more information and to purchase OMGF Pro.*
46
 
47
  == Installation ==
48
 
@@ -108,10 +115,35 @@ No, not yet. But I will definitely try to make it compatible in the future!
108
 
109
  == Screenshots ==
110
 
111
- N/A
 
 
 
112
 
113
  == Changelog ==
114
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115
  = 4.1.3 =
116
  * Fixed bug which would continuously show 'No fonts founds' notice in admin, among others.
117
  * Increased compatibility with caching plugins, which would cause static pages to be served and block OMGF from pointing requests to its Download API.
3
  Tags: google, fonts, gdpr, cache, speed, preload, font-display, webfonts, subsets, remove, minimize, external, requests
4
  Requires at least: 4.6
5
  Tested up to: 5.5
6
+ Stable tag: 4.2.0
7
  Requires PHP: 7.0
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
21
 
22
  = How Does It Work? =
23
 
24
+ After installing the plugin, choose your Optimization Mode: Manual (default) or Automatic.
25
 
26
+ When *Manual* is selected, you can simply configure OMGF to work in the way you want, and run its detection mechanism on an address of your choosing.
27
+
28
+ In *Automatic* Mode, OMGF runs silently in the background and captures any requests made to fonts.googleapis.com or fonts.gstatic.com. When a webpage is first loaded, it reroutes these requests to its own Download API and copies the fonts over to your server. Then it generates a stylesheet for your fonts including EOT, TTF, WOFF and WOFF2 formats to guarantee maximum cross browser compatibility!
29
+
30
+ When the fonts are downloaded and the stylesheet is generated, it rewrites every URL (pointing to fonts.googleapis.com or fonts.gstatic.com) to the locally hosted variant.
31
 
32
  Please keep in mind that, although I try to make the configuration of this plugin as easy as possible, the concept of locally hosting a file or optimizing Google Fonts for *Pagespeed Insights* or *GT Metrix* has proven to be confusing for some people. If you're not sure of what your doing, please consult a SEO expert or Webdeveloper to help you with the configuration of this plugin or [hire me to do it for you](https://ffwp.dev/wordpress/omgf-expert-configuration/).
33
 
34
  = Features =
35
  - Automatically replace registered/enqueued Google Fonts in wp_head() with local copies,
36
  - Automatically remove registered/enqueued Google Fonts from wp_head(),
37
+ - Manage Optimized Google Fonts,
38
+ - Preload above the fold fonts,
39
+ - Don't load certain fonts or entire stylesheets.
40
  - Leverage the font-display (swap) option,
41
  - Serve fonts from CDN,
42
  - Use OMGF with *security through obscurity* plugins.
49
  - Reduce loading time and page size, by forcing the used subset(s) for all Google Fonts requests,
50
  - Remove Resource Hints (preload, preconnect, dns-prefetch) pointing to fonts.googleapis.com or fonts.gstatic.com.
51
 
52
+ *[Purchase OMGF Pro](https://ffwp.dev/wordpress/omgf-pro/) | [Documentation](https://ffwp.dev/docs/omgf-pro/).*
53
 
54
  == Installation ==
55
 
115
 
116
  == Screenshots ==
117
 
118
+ 1. OMGF's Optimize Fonts screen. These settings affect the downloaded files and generated stylesheet(s).
119
+ 2. After you've saved your changes, the Manage Optimized Google Fonts overview will show a list of detected fonts and will allow you to tweak it as you wish.
120
+ 3. Tweak how OMGF's detection mechanism will work and how it'll treat detected fonts.
121
+ 4. Advanced Settings. Change these to make OMGF work with your configuration (if needed). The default settings will suffice for most configurations.
122
 
123
  == Changelog ==
124
 
125
+ = 4.2.0 | The What-4.0-should've-been Edition | October 7th, 2020 =
126
+ * **IMPORTANT NOTICE: If you're upgrading from v4.x.x it's required to Empty your Cache Directory. Otherwise the Optimized Google Fonts Overview will not work.**
127
+ * Added CSS2 (Variable Fonts) compatiblity,
128
+ * No more spaces in filenames of downloaded fonts,
129
+ * Added Optimize Fonts tab, which resembles the 'Generate Stylesheet' tab from v3, and features,
130
+ * Optimization Mode: Manual or Automatic,
131
+ * If Manual is selected, the URL can be specified which should be scanned for Google Fonts,
132
+ * A complete overview of all detected fonts, grouped by stylesheet,
133
+ * Options to preload or unload for each font.
134
+ * Move settings to more sensible places and re-grouped them in 3 groups:
135
+ * Optimize Fonts,
136
+ * Detection Settings,
137
+ * Advanced Settings.
138
+ * OMGF will now throw a notice when a settings is changed which requires the cache to be flushed.
139
+ * Several tweaks and fixes in OMGF's Auto Detection mechanism and Fonts Download API.
140
+ * Fixed issue where OMGF wouldn't detect fonts in weight 400 (and 400 italic).
141
+ * Major UX improvements,
142
+ * Pros and Cons of each Optimization Mode are outlined upon selection,
143
+ * Show loaded while actions are taking place,
144
+ * Cleaned up sidebar and added a clear overview of available documentation.
145
+ * Several tweaks and optimizations in overall performance.
146
+
147
  = 4.1.3 =
148
  * Fixed bug which would continuously show 'No fonts founds' notice in admin, among others.
149
  * Increased compatibility with caching plugins, which would cause static pages to be served and block OMGF from pointing requests to its Download API.
templates/admin/block-welcome.phtml CHANGED
@@ -69,7 +69,7 @@ $tweetUrl = 'https://twitter.com/intent/tweet?text=I+just+optimized+my
69
  <?= __('Do you <span class="dashicons dashicons-heart ffwp-heart"></span> OMGF Pro?', $plugin_text_domain) ;?>
70
  </h2>
71
  <p>
72
- <?= __('Click the button below and receive a unique discount code for 10% off your next purchase!'); ?>
73
  </p>
74
  <p>
75
  <a target="_blank" class="button button-primary button-hero" href="<?= OMGF_Admin_Settings::FFWP_WORDPRESS_PLUGINS_OMGF_PRO . '#edd-reviews-title'; ?>"><span class="dashicons-before dashicons-star-filled"> <?php _e( 'Review', $plugin_text_domain); ?></span></a>
@@ -80,20 +80,12 @@ $tweetUrl = 'https://twitter.com/intent/tweet?text=I+just+optimized+my
80
  <h3>
81
  <?php _e('Need Help?', $plugin_text_domain); ?>
82
  </h3>
83
- <?php if (apply_filters('apply_omgf_pro_promo', true)): ?>
84
- <p>
85
- <?= sprintf(__('%sClick here%s for a comprehensive guide.', $plugin_text_domain), '<a target="_blank" href="' . OMGF_SITE_URL . '/wordpress/host-google-fonts-locally/' . $utmTags . '">', '</a>'); ?>
86
- </p>
87
- <p>
88
- <?= sprintf(__('Visit the %sFAQ%s and %sSupport Forum%s to see if your question has already been answered. If not, ask a question on the Support Forum.', $plugin_text_domain), '<a href="https://wordpress.org/plugins/host-webfonts-local/#description" target="_blank">', '</a>', '<a href="https://wordpress.org/support/plugin/host-webfonts-local">', '</a>'); ?>
89
- </p>
90
- <?php else: ?>
91
  <ul>
92
- <li><a target="_blank" href="https://ffwp.dev/docs/omgf-pro/quick-start/"><?= __('Quick Start Guide', $plugin_text_domain); ?></a></li>
93
- <li><a target="_blank" href="https://ffwp.dev/docs/omgf-pro/faq/"><?= __('FAQ', $plugin_text_domain); ?></a></li>
94
- <li><a target="_blank" href="https://ffwp.dev/contact/"><?= __('Contact', $plugin_text_domain); ?></a></li>
 
95
  </ul>
96
- <?php endif; ?>
97
  <hr />
98
  <h4 class="signature"><?= sprintf(__('Coded with %s in The Netherlands.', $plugin_text_domain), '<span class="dashicons dashicons-heart ffwp-heart"></span>'); ?></h4>
99
  <p class="signature">
69
  <?= __('Do you <span class="dashicons dashicons-heart ffwp-heart"></span> OMGF Pro?', $plugin_text_domain) ;?>
70
  </h2>
71
  <p>
72
+ <?= __('Click the button below and receive a personal discount code for 10% off your next purchase!'); ?>
73
  </p>
74
  <p>
75
  <a target="_blank" class="button button-primary button-hero" href="<?= OMGF_Admin_Settings::FFWP_WORDPRESS_PLUGINS_OMGF_PRO . '#edd-reviews-title'; ?>"><span class="dashicons-before dashicons-star-filled"> <?php _e( 'Review', $plugin_text_domain); ?></span></a>
80
  <h3>
81
  <?php _e('Need Help?', $plugin_text_domain); ?>
82
  </h3>
 
 
 
 
 
 
 
 
83
  <ul>
84
+ <li><a target="_blank" href="<?= apply_filters('omgf_settings_sidebar_quick_start', 'https://ffwp.dev/docs/omgf-pro/quick-start/'); ?>"><?= __('Quick Start Guide', $plugin_text_domain); ?></a></li>
85
+ <li><a target="_blank" href="<?= apply_filters('omgf_settings_sidebar_user_manual', 'https://ffwp.dev/docs/omgf-pro/user-manual/'); ?>"><?= __('User Manual', $plugin_text_domain); ?></a></li>
86
+ <li><a target="_blank" href="<?= apply_filters('omgf_settings_sidebar_faq_link', 'https://wordpress.org/plugins/host-webfonts-local/#description'); ?>"><?= __('FAQ', $plugin_text_domain); ?></a></li>
87
+ <li><a target="_blank" href="<?= apply_filters('omgf_settings_sidebar_get_support_link', 'https://wordpress.org/support/plugin/host-webfonts-local'); ?>"><?= __('Get Support', $plugin_text_domain); ?></a></li>
88
  </ul>
 
89
  <hr />
90
  <h4 class="signature"><?= sprintf(__('Coded with %s in The Netherlands.', $plugin_text_domain), '<span class="dashicons dashicons-heart ffwp-heart"></span>'); ?></h4>
91
  <p class="signature">