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

Version Description

| January 27th, 2021 = * Improved compatibility with WordPress subdirectory installs. * Implemented some actions/filters needed for upcoming release of OMGF Additional Fonts. * Fixed duplicate preload ID's issue. * Fixed some notices/warnings. * Minor UX improvements.

Download this release

Release Info

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

Code changes from version 4.2.4 to 4.2.5

assets/css/omgf-admin.css CHANGED
@@ -9,7 +9,7 @@
9
  *
10
  * @package : OMGF
11
  * @author : Daan van den Bergh
12
- * @copyright: (c) 2020 Daan van den Bergh
13
  * @url : https://daan.dev
14
  * * * * * * * * * * * * * * * * * * * */
15
  /**
@@ -176,4 +176,4 @@
176
  width: 100%;
177
  }
178
  }
179
- /*# sourceMappingURL=omgf-admin.css.map */
9
  *
10
  * @package : OMGF
11
  * @author : Daan van den Bergh
12
+ * @copyright: (c) 2021 Daan van den Bergh
13
  * @url : https://daan.dev
14
  * * * * * * * * * * * * * * * * * * * */
15
  /**
176
  width: 100%;
177
  }
178
  }
179
+ /*# sourceMappingURL=./omgf-admin.css.map */
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;;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"}
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"}
assets/css/omgf-admin.less CHANGED
@@ -9,7 +9,7 @@
9
  *
10
  * @package : OMGF
11
  * @author : Daan van den Bergh
12
- * @copyright: (c) 2020 Daan van den Bergh
13
  * @url : https://daan.dev
14
  * * * * * * * * * * * * * * * * * * * */
15
 
9
  *
10
  * @package : OMGF
11
  * @author : Daan van den Bergh
12
+ * @copyright: (c) 2021 Daan van den Bergh
13
  * @url : https://daan.dev
14
  * * * * * * * * * * * * * * * * * * * */
15
 
assets/js/omgf-admin.js CHANGED
@@ -9,7 +9,7 @@
9
  *
10
  * @package : OMGF
11
  * @author : Daan van den Bergh
12
- * @copyright: (c) 2020 Daan van den Bergh
13
  * @url : https://daan.dev
14
  * * * * * * * * * * * * * * * * * * * */
15
 
@@ -18,7 +18,7 @@ jQuery(document).ready(function ($) {
18
  empty_cache_directory_xhr: false,
19
  optimize_xhr: false,
20
  cache_prefix: '-ul-',
21
-
22
  /**
23
  * Initialize all on click events.
24
  */
@@ -29,12 +29,12 @@ jQuery(document).ready(function ($) {
29
  $('.omgf-optimize-fonts-manage .unload').on('change', this.generate_cache_key);
30
  $('.omgf-optimize-fonts-manage .unload').on('change', this.toggle_preload);
31
  $('.omgf-optimize-fonts-manage .preload').on('change', this.toggle_unload);
32
-
33
  // Buttons
34
  $('.omgf-empty').on('click', this.empty_cache_directory);
35
  $('#omgf-optimize-settings-form').submit(this.show_loader_before_submit);
36
  },
37
-
38
  /**
39
  *
40
  */
@@ -47,102 +47,102 @@ jQuery(document).ready(function ($) {
47
  $('.omgf-optimize-fonts-manual').hide();
48
  }
49
  },
50
-
51
  /**
52
  * Populates the omgf_unload_stylesheets hidden field.
53
  */
54
  unload_stylesheets: function () {
55
- var handle = $(this).closest('tbody');
56
- var id = handle[0].id;
57
- var checked = $('tbody' + '#' + id + ' input.unload:checked').length;
58
- var total = $('tbody' + '#' + id + ' input.unload').length;
59
  var unloaded_stylesheets_option = $('#omgf_unload_stylesheets');
60
- var unloaded_stylesheets = unloaded_stylesheets_option.val().split(',');
61
-
62
  if (checked === total) {
63
  if (unloaded_stylesheets.indexOf(id) === -1) {
64
  unloaded_stylesheets.push(id);
65
  }
66
-
67
  unloaded_stylesheets.join();
68
-
69
  unloaded_stylesheets_option.val(unloaded_stylesheets);
70
  } else {
71
  position = unloaded_stylesheets.indexOf(id);
72
-
73
  if (~position) unloaded_stylesheets.splice(position, 1);
74
-
75
  unloaded_stylesheets_option.val(unloaded_stylesheets);
76
  }
77
  },
78
-
79
  /**
80
  * Generate a new cache key upon each unload change.
81
  */
82
  generate_cache_key: function () {
83
- var current_handle = $(this).data('handle'),
84
  cache_keys_input = $('#omgf_cache_keys'),
85
- cache_keys = cache_keys_input.val().split(','),
86
- checked = $('#' + current_handle + ' input.unload:checked').length,
87
- total = $('#' + current_handle + ' input.unload').length,
88
- cache_key_index = cache_keys.findIndex((key, index) => {
89
  if (key.indexOf(current_handle) !== -1) {
90
  return true;
91
  }
92
  }),
93
- no_cache_key = false;
94
-
95
  /**
96
  * If no or all boxes are checked, (re-)set cache key to default (without random string).
97
  */
98
  if (checked === 0 || checked === total) {
99
  cache_keys[cache_key_index] = current_handle;
100
-
101
  no_cache_key = true;
102
  }
103
-
104
  if (no_cache_key === true) {
105
  cache_keys_input.val(cache_keys.join());
106
-
107
  return;
108
  }
109
-
110
  /**
111
  * Generate a unique cache key if some of this stylesheet's fonts are unloaded.
112
  */
113
  if (cache_key_index !== -1) {
114
  var current_cache_key = cache_keys[cache_key_index];
115
-
116
  var cache_key = omgf_admin.cache_prefix + Math.random().toString(36).substring(2, 7);
117
-
118
  if (current_cache_key.indexOf(omgf_admin.cache_prefix) !== -1) {
119
- var parts = current_cache_key.split(omgf_admin.cache_prefix),
120
- last_part = omgf_admin.get_last_element_index(parts);
121
- parts[last_part] = Math.random().toString(36).substring(2, 7);
122
  current_cache_key = parts[0];
123
- cache_key = omgf_admin.cache_prefix + parts[last_part];
124
  }
125
-
126
  cache_keys[cache_key_index] = current_cache_key + cache_key;
127
  }
128
-
129
  cache_keys_input.val(cache_keys.join());
130
  },
131
-
132
  /**
133
  * Toggle preload option associated with this unload option.
134
  */
135
  toggle_preload: function () {
136
  omgf_admin.toggle(this, 'preload');
137
  },
138
-
139
  /**
140
  * Toggle unload option associated with the current preload option.
141
  */
142
  toggle_unload: function () {
143
  omgf_admin.toggle(this, 'unload');
144
  },
145
-
146
  /**
147
  * Toggle a checkbox.
148
  *
@@ -150,16 +150,16 @@ jQuery(document).ready(function ($) {
150
  * @param option
151
  */
152
  toggle: function (elem, option) {
153
- var this_option = $(elem);
154
  var other_option = $('.' + option + '-' + this_option.data('handle') + '-' + this_option.data('font-id') + '-' + this_option.val() + ' .' + option);
155
-
156
  if (elem.checked) {
157
  other_option.attr('disabled', true);
158
  } else {
159
  other_option.attr('disabled', false);
160
  }
161
  },
162
-
163
  /**
164
  *
165
  * @param array
@@ -168,7 +168,7 @@ jQuery(document).ready(function ($) {
168
  get_last_element_index: function (array) {
169
  return array.length - 1;
170
  },
171
-
172
  /**
173
  * Empty queue, db and cache directory.
174
  */
@@ -176,7 +176,7 @@ jQuery(document).ready(function ($) {
176
  if (omgf_admin.empty_cache_directory_xhr) {
177
  omgf_admin.empty_cache_directory_xhr.abort();
178
  }
179
-
180
  omgf_admin.empty_cache_directory_xhr = $.ajax({
181
  type: 'POST',
182
  url: ajaxurl,
@@ -191,11 +191,11 @@ jQuery(document).ready(function ($) {
191
  }
192
  });
193
  },
194
-
195
  show_loader_before_submit: function (e) {
196
  omgf_admin.show_loader();
197
  },
198
-
199
  /**
200
  *
201
  */
@@ -203,9 +203,9 @@ jQuery(document).ready(function ($) {
203
  $('#wpcontent').append('<div class="omgf-loading"><span class="spinner is-active"></span></div>');
204
  }
205
  };
206
-
207
  omgf_admin.init();
208
-
209
  $('#omgf_relative_url').click(function () {
210
  if (this.checked === true) {
211
  $('#omgf_cdn_url').prop('disabled', true);
9
  *
10
  * @package : OMGF
11
  * @author : Daan van den Bergh
12
+ * @copyright: (c) 2021 Daan van den Bergh
13
  * @url : https://daan.dev
14
  * * * * * * * * * * * * * * * * * * * */
15
 
18
  empty_cache_directory_xhr: false,
19
  optimize_xhr: false,
20
  cache_prefix: '-ul-',
21
+
22
  /**
23
  * Initialize all on click events.
24
  */
29
  $('.omgf-optimize-fonts-manage .unload').on('change', this.generate_cache_key);
30
  $('.omgf-optimize-fonts-manage .unload').on('change', this.toggle_preload);
31
  $('.omgf-optimize-fonts-manage .preload').on('change', this.toggle_unload);
32
+
33
  // Buttons
34
  $('.omgf-empty').on('click', this.empty_cache_directory);
35
  $('#omgf-optimize-settings-form').submit(this.show_loader_before_submit);
36
  },
37
+
38
  /**
39
  *
40
  */
47
  $('.omgf-optimize-fonts-manual').hide();
48
  }
49
  },
50
+
51
  /**
52
  * Populates the omgf_unload_stylesheets hidden field.
53
  */
54
  unload_stylesheets: function () {
55
+ var handle = $(this).closest('tbody');
56
+ var id = handle[0].id;
57
+ var checked = $('tbody' + '#' + id + ' input.unload:checked').length;
58
+ var total = $('tbody' + '#' + id + ' input.unload').length;
59
  var unloaded_stylesheets_option = $('#omgf_unload_stylesheets');
60
+ var unloaded_stylesheets = unloaded_stylesheets_option.val().split(',');
61
+
62
  if (checked === total) {
63
  if (unloaded_stylesheets.indexOf(id) === -1) {
64
  unloaded_stylesheets.push(id);
65
  }
66
+
67
  unloaded_stylesheets.join();
68
+
69
  unloaded_stylesheets_option.val(unloaded_stylesheets);
70
  } else {
71
  position = unloaded_stylesheets.indexOf(id);
72
+
73
  if (~position) unloaded_stylesheets.splice(position, 1);
74
+
75
  unloaded_stylesheets_option.val(unloaded_stylesheets);
76
  }
77
  },
78
+
79
  /**
80
  * Generate a new cache key upon each unload change.
81
  */
82
  generate_cache_key: function () {
83
+ var current_handle = $(this).data('handle'),
84
  cache_keys_input = $('#omgf_cache_keys'),
85
+ cache_keys = cache_keys_input.val().split(','),
86
+ checked = $('#' + current_handle + ' input.unload:checked').length,
87
+ total = $('#' + current_handle + ' input.unload').length,
88
+ cache_key_index = cache_keys.findIndex((key, index) => {
89
  if (key.indexOf(current_handle) !== -1) {
90
  return true;
91
  }
92
  }),
93
+ no_cache_key = false;
94
+
95
  /**
96
  * If no or all boxes are checked, (re-)set cache key to default (without random string).
97
  */
98
  if (checked === 0 || checked === total) {
99
  cache_keys[cache_key_index] = current_handle;
100
+
101
  no_cache_key = true;
102
  }
103
+
104
  if (no_cache_key === true) {
105
  cache_keys_input.val(cache_keys.join());
106
+
107
  return;
108
  }
109
+
110
  /**
111
  * Generate a unique cache key if some of this stylesheet's fonts are unloaded.
112
  */
113
  if (cache_key_index !== -1) {
114
  var current_cache_key = cache_keys[cache_key_index];
115
+
116
  var cache_key = omgf_admin.cache_prefix + Math.random().toString(36).substring(2, 7);
117
+
118
  if (current_cache_key.indexOf(omgf_admin.cache_prefix) !== -1) {
119
+ var parts = current_cache_key.split(omgf_admin.cache_prefix),
120
+ last_part = omgf_admin.get_last_element_index(parts);
121
+ parts[last_part] = Math.random().toString(36).substring(2, 7);
122
  current_cache_key = parts[0];
123
+ cache_key = omgf_admin.cache_prefix + parts[last_part];
124
  }
125
+
126
  cache_keys[cache_key_index] = current_cache_key + cache_key;
127
  }
128
+
129
  cache_keys_input.val(cache_keys.join());
130
  },
131
+
132
  /**
133
  * Toggle preload option associated with this unload option.
134
  */
135
  toggle_preload: function () {
136
  omgf_admin.toggle(this, 'preload');
137
  },
138
+
139
  /**
140
  * Toggle unload option associated with the current preload option.
141
  */
142
  toggle_unload: function () {
143
  omgf_admin.toggle(this, 'unload');
144
  },
145
+
146
  /**
147
  * Toggle a checkbox.
148
  *
150
  * @param option
151
  */
152
  toggle: function (elem, option) {
153
+ var this_option = $(elem);
154
  var other_option = $('.' + option + '-' + this_option.data('handle') + '-' + this_option.data('font-id') + '-' + this_option.val() + ' .' + option);
155
+
156
  if (elem.checked) {
157
  other_option.attr('disabled', true);
158
  } else {
159
  other_option.attr('disabled', false);
160
  }
161
  },
162
+
163
  /**
164
  *
165
  * @param array
168
  get_last_element_index: function (array) {
169
  return array.length - 1;
170
  },
171
+
172
  /**
173
  * Empty queue, db and cache directory.
174
  */
176
  if (omgf_admin.empty_cache_directory_xhr) {
177
  omgf_admin.empty_cache_directory_xhr.abort();
178
  }
179
+
180
  omgf_admin.empty_cache_directory_xhr = $.ajax({
181
  type: 'POST',
182
  url: ajaxurl,
191
  }
192
  });
193
  },
194
+
195
  show_loader_before_submit: function (e) {
196
  omgf_admin.show_loader();
197
  },
198
+
199
  /**
200
  *
201
  */
203
  $('#wpcontent').append('<div class="omgf-loading"><span class="spinner is-active"></span></div>');
204
  }
205
  };
206
+
207
  omgf_admin.init();
208
+
209
  $('#omgf_relative_url').click(function () {
210
  if (this.checked === true) {
211
  $('#omgf_cdn_url').prop('disabled', true);
ffwp-autoload.php CHANGED
@@ -1,8 +1,8 @@
1
  <?php
2
  /* * * * * * * * * * * * * * * * * * * * * *
3
  * @author : Daan van den Bergh
4
- * @url : https://ffwp.dev/wordpress-plugins/
5
- * @copyright: (c) 2020 Daan van den Bergh
6
  * @license : GPL2v2 or later
7
  * * * * * * * * * * * * * * * * * * * * * */
8
 
1
  <?php
2
  /* * * * * * * * * * * * * * * * * * * * * *
3
  * @author : Daan van den Bergh
4
+ * @url : https://ffw.press/wordpress-plugins/
5
+ * @copyright: (c) 2021 Daan van den Bergh
6
  * @license : GPL2v2 or later
7
  * * * * * * * * * * * * * * * * * * * * * */
8
 
host-webfonts-local.php CHANGED
@@ -1,26 +1,27 @@
1
  <?php
 
2
  /**
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.4
8
- * Author: Daan (from Fast FW Press)
9
- * Author URI: https://ffwp.dev
10
  * License: GPL2v2 or later
11
  * Text Domain: host-webfonts-local
12
  * @formatter:on
13
  */
14
 
15
- defined( 'ABSPATH' ) || exit;
16
 
17
  /**
18
  * Define constants.
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.
@@ -29,37 +30,39 @@ define( 'OMGF_STATIC_VERSION', '4.2.0' );
29
  *
30
  * @return mixed|void
31
  */
32
- function omgf_autoload ( $class ) {
33
- $path = explode( '_', $class );
34
-
35
- if ( $path[0] != 'OMGF' ) {
 
36
  return;
37
  }
38
-
39
- if ( ! class_exists( 'FFWP_Autoloader' ) ) {
40
- require_once( OMGF_PLUGIN_DIR . 'ffwp-autoload.php' );
41
  }
42
-
43
- $autoload = new FFWP_Autoloader( $class );
44
-
45
  return include OMGF_PLUGIN_DIR . 'includes/' . $autoload->load();
46
  }
47
 
48
- spl_autoload_register( 'omgf_autoload' );
49
 
50
  /**
51
  * All systems GO!!!
52
  *
53
  * @return OMGF
54
  */
55
- function omgf_init () {
 
56
  static $omgf = null;
57
-
58
- if ( $omgf === null ) {
59
  $omgf = new OMGF();
60
  }
61
-
62
  return $omgf;
63
  }
64
 
65
- add_action( 'plugins_loaded', 'omgf_init', 50 );
1
  <?php
2
+
3
  /**
4
  * @formatter:off
5
  * Plugin Name: OMGF
6
  * Plugin URI: https://daan.dev/wordpress-plugins/host-google-fonts-locally
7
  * Description: Minimize DNS requests, leverage browser cache and speed up WordPress by saving Google Fonts to your server and removing external Google Fonts requests.
8
+ * Version: 4.2.5
9
+ * Author: Daan (from FFW.Press)
10
+ * Author URI: https://ffw.press
11
  * License: GPL2v2 or later
12
  * Text Domain: host-webfonts-local
13
  * @formatter:on
14
  */
15
 
16
+ defined('ABSPATH') || exit;
17
 
18
  /**
19
  * Define constants.
20
  */
21
+ define('OMGF_PLUGIN_DIR', plugin_dir_path(__FILE__));
22
+ define('OMGF_PLUGIN_FILE', __FILE__);
23
+ define('OMGF_PLUGIN_BASENAME', plugin_basename(OMGF_PLUGIN_FILE));
24
+ define('OMGF_STATIC_VERSION', '4.2.0');
25
 
26
  /**
27
  * Takes care of loading classes on demand.
30
  *
31
  * @return mixed|void
32
  */
33
+ function omgf_autoload($class)
34
+ {
35
+ $path = explode('_', $class);
36
+
37
+ if ($path[0] != 'OMGF') {
38
  return;
39
  }
40
+
41
+ if (!class_exists('FFWP_Autoloader')) {
42
+ require_once(OMGF_PLUGIN_DIR . 'ffwp-autoload.php');
43
  }
44
+
45
+ $autoload = new FFWP_Autoloader($class);
46
+
47
  return include OMGF_PLUGIN_DIR . 'includes/' . $autoload->load();
48
  }
49
 
50
+ spl_autoload_register('omgf_autoload');
51
 
52
  /**
53
  * All systems GO!!!
54
  *
55
  * @return OMGF
56
  */
57
+ function omgf_init()
58
+ {
59
  static $omgf = null;
60
+
61
+ if ($omgf === null) {
62
  $omgf = new OMGF();
63
  }
64
+
65
  return $omgf;
66
  }
67
 
68
+ add_action('plugins_loaded', 'omgf_init', 50);
includes/admin/class-notice.php CHANGED
@@ -10,20 +10,20 @@
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_Notice
20
  {
21
  const OMGF_ADMIN_NOTICE_TRANSIENT = 'omgf_admin_notice';
22
  const OMGF_ADMIN_NOTICE_EXPIRATION = 60;
23
-
24
  /** @var array $notices */
25
  public static $notices = [];
26
-
27
  /**
28
  * @param $message
29
  * @param string $type (info|warning|error|success)
@@ -31,73 +31,76 @@ class OMGF_Admin_Notice
31
  * @param bool $json
32
  * @param int $code
33
  */
34
- public static function set_notice ( $message, $message_id = '', $die = true, $type = 'success', $code = 200, $screen_id = 'all' ) {
35
- self::$notices = get_transient( self::OMGF_ADMIN_NOTICE_TRANSIENT );
36
-
37
- if ( ! self::$notices ) {
 
38
  self::$notices = [];
39
  }
40
-
41
- self::$notices[ $screen_id ][ $type ][ $message_id ] = $message;
42
-
43
- set_transient( self::OMGF_ADMIN_NOTICE_TRANSIENT, self::$notices, self::OMGF_ADMIN_NOTICE_EXPIRATION );
44
-
45
- if ( $die ) {
46
- switch ( $type ) {
47
  case 'error':
48
- wp_send_json_error( $message, $code );
49
  break;
50
  default:
51
- wp_send_json_success( $message, $code );
52
  }
53
  }
54
  }
55
-
56
  /**
57
  * @param string $message_id
58
  * @param string $type
59
  * @param string $screen_id
60
  */
61
- public static function unset_notice ( $message_id = '', $type = 'info', $screen_id = 'all' ) {
62
- self::$notices = get_transient( self::OMGF_ADMIN_NOTICE_TRANSIENT );
63
-
64
- if ( isset( self::$notices [ $screen_id ][ $type ][ $message_id ] ) ) {
65
- unset( self::$notices [ $screen_id ][ $type ][ $message_id ] );
 
66
  }
67
-
68
- if ( is_array( self::$notices ) && empty( self::$notices [ $screen_id ] [ $type ] ) ) {
69
- unset ( self::$notices [ $screen_id ] [ $type ] );
70
  }
71
-
72
- set_transient( self::OMGF_ADMIN_NOTICE_TRANSIENT, self::$notices, self::OMGF_ADMIN_NOTICE_EXPIRATION );
73
  }
74
-
75
  /**
76
  * Prints notice (if any) grouped by type.
77
  */
78
- public static function print_notices () {
79
- $admin_notices = get_transient( self::OMGF_ADMIN_NOTICE_TRANSIENT );
80
-
81
- if ( is_array( $admin_notices ) ) {
 
82
  $current_screen = get_current_screen();
83
-
84
- foreach ( $admin_notices as $screen => $notice ) {
85
- if ( $current_screen->id != $screen && $screen != 'all' ) {
86
  continue;
87
  }
88
-
89
- foreach ( $notice as $type => $message ) {
90
- ?>
91
- <div id="message" class="notice notice-<?php echo $type; ?> is-dismissible">
92
- <?php foreach ( $message as $line ): ?>
93
- <p><?= $line; ?></p>
94
  <?php endforeach; ?>
95
- </div>
96
- <?php
97
  }
98
  }
99
  }
100
-
101
- delete_transient( self::OMGF_ADMIN_NOTICE_TRANSIENT );
102
  }
103
  }
10
  *
11
  * @package : OMGF
12
  * @author : Daan van den Bergh
13
+ * @copyright: (c) 2021 Daan van den Bergh
14
  * @url : https://daan.dev
15
  * * * * * * * * * * * * * * * * * * * */
16
 
17
+ defined('ABSPATH') || exit;
18
 
19
  class OMGF_Admin_Notice
20
  {
21
  const OMGF_ADMIN_NOTICE_TRANSIENT = 'omgf_admin_notice';
22
  const OMGF_ADMIN_NOTICE_EXPIRATION = 60;
23
+
24
  /** @var array $notices */
25
  public static $notices = [];
26
+
27
  /**
28
  * @param $message
29
  * @param string $type (info|warning|error|success)
31
  * @param bool $json
32
  * @param int $code
33
  */
34
+ public static function set_notice($message, $message_id = '', $die = true, $type = 'success', $code = 200, $screen_id = 'all')
35
+ {
36
+ self::$notices = get_transient(self::OMGF_ADMIN_NOTICE_TRANSIENT);
37
+
38
+ if (!self::$notices) {
39
  self::$notices = [];
40
  }
41
+
42
+ self::$notices[$screen_id][$type][$message_id] = $message;
43
+
44
+ set_transient(self::OMGF_ADMIN_NOTICE_TRANSIENT, self::$notices, self::OMGF_ADMIN_NOTICE_EXPIRATION);
45
+
46
+ if ($die) {
47
+ switch ($type) {
48
  case 'error':
49
+ wp_send_json_error($message, $code);
50
  break;
51
  default:
52
+ wp_send_json_success($message, $code);
53
  }
54
  }
55
  }
56
+
57
  /**
58
  * @param string $message_id
59
  * @param string $type
60
  * @param string $screen_id
61
  */
62
+ public static function unset_notice($message_id = '', $type = 'info', $screen_id = 'all')
63
+ {
64
+ self::$notices = get_transient(self::OMGF_ADMIN_NOTICE_TRANSIENT);
65
+
66
+ if (isset(self::$notices[$screen_id][$type][$message_id])) {
67
+ unset(self::$notices[$screen_id][$type][$message_id]);
68
  }
69
+
70
+ if (is_array(self::$notices) && empty(self::$notices[$screen_id][$type])) {
71
+ unset(self::$notices[$screen_id][$type]);
72
  }
73
+
74
+ set_transient(self::OMGF_ADMIN_NOTICE_TRANSIENT, self::$notices, self::OMGF_ADMIN_NOTICE_EXPIRATION);
75
  }
76
+
77
  /**
78
  * Prints notice (if any) grouped by type.
79
  */
80
+ public static function print_notices()
81
+ {
82
+ $admin_notices = get_transient(self::OMGF_ADMIN_NOTICE_TRANSIENT);
83
+
84
+ if (is_array($admin_notices)) {
85
  $current_screen = get_current_screen();
86
+
87
+ foreach ($admin_notices as $screen => $notice) {
88
+ if ($current_screen->id != $screen && $screen != 'all') {
89
  continue;
90
  }
91
+
92
+ foreach ($notice as $type => $message) {
93
+ ?>
94
+ <div id="message" class="notice notice-<?php echo $type; ?> is-dismissible">
95
+ <?php foreach ($message as $line) : ?>
96
+ <p><?= $line; ?></p>
97
  <?php endforeach; ?>
98
+ </div>
99
+ <?php
100
  }
101
  }
102
  }
103
+
104
+ delete_transient(self::OMGF_ADMIN_NOTICE_TRANSIENT);
105
  }
106
  }
includes/admin/class-settings.php CHANGED
@@ -10,11 +10,11 @@
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 extends OMGF_Admin
20
  {
@@ -24,7 +24,7 @@ class OMGF_Admin_Settings extends OMGF_Admin
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
  */
@@ -73,7 +73,7 @@ class OMGF_Admin_Settings extends OMGF_Admin
73
  'tibetan' => 'Tibetan',
74
  'vietnamese' => 'Vietnamese'
75
  ];
76
-
77
  /**
78
  * Optimize Fonts
79
  */
@@ -86,12 +86,12 @@ class OMGF_Admin_Settings extends OMGF_Admin
86
  const OMGF_OPTIMIZE_SETTING_UNLOAD_FONTS = 'omgf_unload_fonts';
87
  const OMGF_OPTIMIZE_SETTING_UNLOAD_STYLESHEETS = 'omgf_unload_stylesheets';
88
  const OMGF_OPTIMIZE_SETTING_CACHE_KEYS = 'omgf_cache_keys';
89
-
90
  /**
91
  * Detection Settings
92
  */
93
  const OMGF_DETECTION_SETTING_FONT_PROCESSING = 'omgf_font_processing';
94
-
95
  /**
96
  * Advanced Settings
97
  */
@@ -100,255 +100,269 @@ class OMGF_Admin_Settings extends OMGF_Admin
100
  const OMGF_ADV_SETTING_CDN_URL = 'omgf_cdn_url';
101
  const OMGF_ADV_SETTING_UNINSTALL = 'omgf_uninstall';
102
  const OMGF_ADV_SETTING_RELATIVE_URL = 'omgf_relative_url';
103
-
104
  /**
105
  * Miscellaneous
106
  */
107
  const OMGF_OPTIONS_GENERAL_PAGE_OPTIMIZE_WEBFONTS = 'options-general.php?page=optimize-webfonts';
108
- const FFWP_WORDPRESS_PLUGINS_OMGF_PRO = 'https://ffwp.dev/wordpress/omgf-pro/';
109
-
110
  /** @var string $active_tab */
111
  private $active_tab;
112
-
113
  /** @var string $page */
114
  private $page;
115
-
116
  /** @var string $plugin_text_domain */
117
  private $plugin_text_domain = 'host-webfonts-local';
118
-
119
  /** @var string|null */
120
  private $submit_button_text = null;
121
-
122
  /**
123
  * OMGF_Admin_Settings constructor.
124
  */
125
- public function __construct () {
 
126
  parent::__construct();
127
-
128
- $this->active_tab = isset( $_GET['tab'] ) ? $_GET['tab'] : self::OMGF_SETTINGS_FIELD_OPTIMIZE;
129
- $this->page = isset( $_GET['page'] ) ? $_GET['page'] : '';
130
-
131
- add_action( 'admin_menu', [ $this, 'create_menu' ] );
132
- add_filter( 'plugin_action_links_' . plugin_basename( OMGF_PLUGIN_FILE ), [ $this, 'create_settings_link' ] );
133
-
134
- if ( $this->page !== 'optimize-webfonts' ) {
135
  return;
136
  }
137
-
138
  if ($this->active_tab == self::OMGF_SETTINGS_FIELD_OPTIMIZE) {
139
- $this->submit_button_text = __('Save & Optimize', $this->plugin_text_domain);
140
- }
141
-
142
  // Tabs
143
- add_action( 'omgf_settings_tab', [ $this, 'optimize_fonts_tab' ], 0 );
144
- add_action( 'omgf_settings_tab', [ $this, 'detection_settings_tab' ], 1 );
145
- add_action( 'omgf_settings_tab', [ $this, 'advanced_settings_tab' ], 2 );
146
-
147
  // Content
148
- add_action( 'omgf_settings_content', [ $this, 'optimize_fonts_content' ], 0 );
149
- add_action( 'omgf_settings_content', [ $this, 'detection_settings_content' ], 1 );
150
- add_action( 'omgf_settings_content', [ $this, 'advanced_settings_content' ], 2 );
151
  }
152
-
153
  /**
154
  * Creates the menu item.
155
  */
156
- public function create_menu () {
 
157
  add_options_page(
158
  'OMGF',
159
  'Optimize Google Fonts',
160
  'manage_options',
161
  'optimize-webfonts',
162
- [ $this, 'create_settings_page' ]
163
  );
164
-
165
  // @formatter:off
166
- add_action( 'admin_init', [ $this, 'register_settings' ] );
167
  // @formatter:on
168
  }
169
-
170
  /**
171
  * Display the settings page.
172
  */
173
- public function create_settings_page () {
174
- if ( ! current_user_can( 'manage_options' ) ) {
175
- wp_die( __( "You're not cool enough to access this page.", $this->plugin_text_domain ) );
 
176
  }
177
- ?>
178
- <div class="wrap omgf">
179
- <h1><?= apply_filters( 'omgf_settings_page_title', __( 'OMGF | Optimize My Google Fonts', $this->plugin_text_domain ) ); ?></h1>
180
-
181
- <p>
182
- <?= get_plugin_data( OMGF_PLUGIN_FILE )['Description']; ?>
183
- </p>
184
-
185
- <div class="settings-column left">
186
- <h2 class="omgf-nav nav-tab-wrapper">
187
- <?php do_action( 'omgf_settings_tab' ); ?>
188
- </h2>
189
-
190
- <?php do_action( 'omgf_settings_content' ); ?>
191
- </div>
192
-
193
- <div class="settings-column right">
194
- <div id="omgf-welcome-panel" class="welcome-panel">
195
- <?php $this->get_template( 'welcome' ); ?>
196
- </div>
197
- </div>
198
- </div>
199
- <?php
200
  }
201
-
202
  /**
203
  * Register all settings.
204
  *
205
  * @throws ReflectionException
206
  */
207
- public function register_settings () {
208
- if ( $this->active_tab !== self::OMGF_SETTINGS_FIELD_OPTIMIZE
209
- && $this->active_tab !== self::OMGF_SETTINGS_FIELD_DETECTION
210
- && $this->active_tab !== self::OMGF_SETTINGS_FIELD_ADVANCED
 
 
211
  ) {
212
- $this->active_tab = self::OMGF_SETTINGS_FIELD_OPTIMIZE;
213
  }
214
-
215
- foreach ( $this->get_settings() as $constant => $value ) {
216
  register_setting(
217
  $this->active_tab,
218
  $value
219
  );
220
  }
221
  }
222
-
223
  /**
224
  * Get all settings using the constants in this class.
225
  *
226
  * @return array
227
  * @throws ReflectionException
228
  */
229
- public function get_settings () {
230
- $reflection = new ReflectionClass( $this );
231
- $constants = apply_filters( 'omgf_settings_constants', $reflection->getConstants() );
232
-
233
- switch ( $this->active_tab ) {
234
- case ( self::OMGF_SETTINGS_FIELD_DETECTION ):
 
235
  $needle = 'OMGF_DETECTION_SETTING_';
236
  break;
237
- case ( self::OMGF_SETTINGS_FIELD_ADVANCED ):
238
  $needle = 'OMGF_ADV_SETTING_';
239
  break;
240
  default:
241
- $needle = 'OMGF_OPTIMIZE_SETTING_';
242
  }
243
-
244
  return array_filter(
245
  $constants,
246
- function ( $key ) use ( $needle ) {
247
- return strpos( $key, $needle ) !== false;
248
  },
249
  ARRAY_FILTER_USE_KEY
250
  );
251
  }
252
-
253
- public function optimize_fonts_tab () {
254
- $this->generate_tab( self::OMGF_SETTINGS_FIELD_OPTIMIZE, 'dashicons-performance', __( 'Optimize Fonts', $this->plugin_text_domain ) );
 
255
  }
256
-
257
  /**
258
  * Add Basic Settings Tab to Settings Screen.
259
  */
260
- public function detection_settings_tab () {
261
- $this->generate_tab( self::OMGF_SETTINGS_FIELD_DETECTION, 'dashicons-search', __( 'Detection Settings', $this->plugin_text_domain ) );
 
262
  }
263
-
264
  /**
265
  * Add Advanced Settings Tab to Settings Screen.
266
  */
267
- public function advanced_settings_tab () {
268
- $this->generate_tab( self::OMGF_SETTINGS_FIELD_ADVANCED, 'dashicons-admin-settings', __( 'Advanced Settings', $this->plugin_text_domain ) );
 
269
  }
270
-
271
  /**
272
  * @param $id
273
  * @param null $icon
274
  * @param null $label
275
  */
276
- private function generate_tab ( $id, $icon = null, $label = null ) {
277
- ?>
278
- <a class="nav-tab dashicons-before <?= $icon; ?> <?= $this->active_tab == $id ? 'nav-tab-active' : ''; ?>"
279
- href="<?= $this->generate_tab_link( $id ); ?>">
280
  <?= $label; ?>
281
- </a>
282
- <?php
283
  }
284
-
285
  /**
286
  * @param $tab
287
  *
288
  * @return string
289
  */
290
- private function generate_tab_link ( $tab ) {
291
- return admin_url( self::OMGF_OPTIONS_GENERAL_PAGE_OPTIMIZE_WEBFONTS . "&tab=$tab" );
 
292
  }
293
-
294
  /**
295
  *
296
  */
297
- public function optimize_fonts_content () {
298
- $this->do_settings_content( self::OMGF_SETTINGS_FIELD_OPTIMIZE );
 
299
  }
300
-
301
  /**
302
  * Render Basic Settings content
303
  */
304
- public function detection_settings_content () {
305
- $this->do_settings_content( self::OMGF_SETTINGS_FIELD_DETECTION );
 
306
  }
307
-
308
  /**
309
  * Render Advanced Settings content
310
  */
311
- public function advanced_settings_content () {
312
- $this->do_settings_content( self::OMGF_SETTINGS_FIELD_ADVANCED );
 
313
  }
314
-
315
  /**
316
  * @param $field
317
  */
318
- private function do_settings_content ( $field ) {
319
- if ( $this->active_tab != $field ) {
 
320
  return;
321
  }
322
- ?>
323
- <form id="<?= $field; ?>-form" name="omgf-settings-form" method="post" action="<?= admin_url( 'options.php?tab=' . $this->active_tab ); ?>"
324
- autocomplete="off">
325
  <?php
326
- settings_fields( $field );
327
- do_settings_sections( $field );
328
-
329
- do_action( 'omgf_before_settings_form_settings' );
330
-
331
- echo apply_filters( str_replace( '-', '_', $field ) . '_content', '' );
332
-
333
- do_action( 'omgf_after_settings_form_settings' );
334
-
335
- submit_button( $this->submit_button_text, 'primary', 'submit', false );
336
  ?>
337
- <a id="omgf-empty" class="omgf-empty button-cancel"><?php _e( 'Empty Cache Directory', $this->plugin_text_domain ); ?></a>
338
- </form>
339
- <?php
340
  }
341
-
342
  /**
343
  * @param $links
344
  *
345
  * @return mixed
346
  */
347
- public function create_settings_link ( $links ) {
 
348
  $adminUrl = admin_url() . self::OMGF_OPTIONS_GENERAL_PAGE_OPTIMIZE_WEBFONTS;
349
- $settingsLink = "<a href='$adminUrl'>" . __( 'Settings' ) . "</a>";
350
- array_push( $links, $settingsLink );
351
-
352
  return $links;
353
  }
354
  }
10
  *
11
  * @package : OMGF
12
  * @author : Daan van den Bergh
13
+ * @copyright: (c) 2021 Daan van den Bergh
14
  * @url : https://daan.dev
15
  * * * * * * * * * * * * * * * * * * * */
16
 
17
+ defined('ABSPATH') || exit;
18
 
19
  class OMGF_Admin_Settings extends OMGF_Admin
20
  {
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
  */
73
  'tibetan' => 'Tibetan',
74
  'vietnamese' => 'Vietnamese'
75
  ];
76
+
77
  /**
78
  * Optimize Fonts
79
  */
86
  const OMGF_OPTIMIZE_SETTING_UNLOAD_FONTS = 'omgf_unload_fonts';
87
  const OMGF_OPTIMIZE_SETTING_UNLOAD_STYLESHEETS = 'omgf_unload_stylesheets';
88
  const OMGF_OPTIMIZE_SETTING_CACHE_KEYS = 'omgf_cache_keys';
89
+
90
  /**
91
  * Detection Settings
92
  */
93
  const OMGF_DETECTION_SETTING_FONT_PROCESSING = 'omgf_font_processing';
94
+
95
  /**
96
  * Advanced Settings
97
  */
100
  const OMGF_ADV_SETTING_CDN_URL = 'omgf_cdn_url';
101
  const OMGF_ADV_SETTING_UNINSTALL = 'omgf_uninstall';
102
  const OMGF_ADV_SETTING_RELATIVE_URL = 'omgf_relative_url';
103
+
104
  /**
105
  * Miscellaneous
106
  */
107
  const OMGF_OPTIONS_GENERAL_PAGE_OPTIMIZE_WEBFONTS = 'options-general.php?page=optimize-webfonts';
108
+ const FFWP_WORDPRESS_PLUGINS_OMGF_PRO = 'https://ffw.press/wordpress/omgf-pro/';
109
+
110
  /** @var string $active_tab */
111
  private $active_tab;
112
+
113
  /** @var string $page */
114
  private $page;
115
+
116
  /** @var string $plugin_text_domain */
117
  private $plugin_text_domain = 'host-webfonts-local';
118
+
119
  /** @var string|null */
120
  private $submit_button_text = null;
121
+
122
  /**
123
  * OMGF_Admin_Settings constructor.
124
  */
125
+ public function __construct()
126
+ {
127
  parent::__construct();
128
+
129
+ $this->active_tab = isset($_GET['tab']) ? $_GET['tab'] : self::OMGF_SETTINGS_FIELD_OPTIMIZE;
130
+ $this->page = isset($_GET['page']) ? $_GET['page'] : '';
131
+
132
+ add_action('admin_menu', [$this, 'create_menu']);
133
+ add_filter('plugin_action_links_' . plugin_basename(OMGF_PLUGIN_FILE), [$this, 'create_settings_link']);
134
+
135
+ if ($this->page !== 'optimize-webfonts') {
136
  return;
137
  }
138
+
139
  if ($this->active_tab == self::OMGF_SETTINGS_FIELD_OPTIMIZE) {
140
+ $this->submit_button_text = __('Save & Optimize', $this->plugin_text_domain);
141
+ }
142
+
143
  // Tabs
144
+ add_action('omgf_settings_tab', [$this, 'optimize_fonts_tab'], 0);
145
+ add_action('omgf_settings_tab', [$this, 'detection_settings_tab'], 1);
146
+ add_action('omgf_settings_tab', [$this, 'advanced_settings_tab'], 2);
147
+
148
  // Content
149
+ add_action('omgf_settings_content', [$this, 'optimize_fonts_content'], 0);
150
+ add_action('omgf_settings_content', [$this, 'detection_settings_content'], 1);
151
+ add_action('omgf_settings_content', [$this, 'advanced_settings_content'], 2);
152
  }
153
+
154
  /**
155
  * Creates the menu item.
156
  */
157
+ public function create_menu()
158
+ {
159
  add_options_page(
160
  'OMGF',
161
  'Optimize Google Fonts',
162
  'manage_options',
163
  'optimize-webfonts',
164
+ [$this, 'create_settings_page']
165
  );
166
+
167
  // @formatter:off
168
+ add_action('admin_init', [$this, 'register_settings']);
169
  // @formatter:on
170
  }
171
+
172
  /**
173
  * Display the settings page.
174
  */
175
+ public function create_settings_page()
176
+ {
177
+ if (!current_user_can('manage_options')) {
178
+ wp_die(__("You're not cool enough to access this page.", $this->plugin_text_domain));
179
  }
180
+ ?>
181
+ <div class="wrap omgf">
182
+ <h1><?= apply_filters('omgf_settings_page_title', __('OMGF | Optimize My Google Fonts', $this->plugin_text_domain)); ?></h1>
183
+
184
+ <p>
185
+ <?= get_plugin_data(OMGF_PLUGIN_FILE)['Description']; ?>
186
+ </p>
187
+
188
+ <div class="settings-column left">
189
+ <h2 class="omgf-nav nav-tab-wrapper">
190
+ <?php do_action('omgf_settings_tab'); ?>
191
+ </h2>
192
+
193
+ <?php do_action('omgf_settings_content'); ?>
194
+ </div>
195
+
196
+ <div class="settings-column right">
197
+ <div id="omgf-welcome-panel" class="welcome-panel">
198
+ <?php $this->get_template('welcome'); ?>
199
+ </div>
200
+ </div>
201
+ </div>
202
+ <?php
203
  }
204
+
205
  /**
206
  * Register all settings.
207
  *
208
  * @throws ReflectionException
209
  */
210
+ public function register_settings()
211
+ {
212
+ if (
213
+ $this->active_tab !== self::OMGF_SETTINGS_FIELD_OPTIMIZE
214
+ && $this->active_tab !== self::OMGF_SETTINGS_FIELD_DETECTION
215
+ && $this->active_tab !== self::OMGF_SETTINGS_FIELD_ADVANCED
216
  ) {
217
+ $this->active_tab = apply_filters('omgf_admin_settings_active_tab', self::OMGF_SETTINGS_FIELD_OPTIMIZE);
218
  }
219
+
220
+ foreach ($this->get_settings() as $constant => $value) {
221
  register_setting(
222
  $this->active_tab,
223
  $value
224
  );
225
  }
226
  }
227
+
228
  /**
229
  * Get all settings using the constants in this class.
230
  *
231
  * @return array
232
  * @throws ReflectionException
233
  */
234
+ public function get_settings()
235
+ {
236
+ $reflection = new ReflectionClass($this);
237
+ $constants = apply_filters('omgf_settings_constants', $reflection->getConstants());
238
+
239
+ switch ($this->active_tab) {
240
+ case (self::OMGF_SETTINGS_FIELD_DETECTION):
241
  $needle = 'OMGF_DETECTION_SETTING_';
242
  break;
243
+ case (self::OMGF_SETTINGS_FIELD_ADVANCED):
244
  $needle = 'OMGF_ADV_SETTING_';
245
  break;
246
  default:
247
+ $needle = apply_filters('omgf_settings_needle', 'OMGF_OPTIMIZE_SETTING_');
248
  }
249
+
250
  return array_filter(
251
  $constants,
252
+ function ($key) use ($needle) {
253
+ return strpos($key, $needle) !== false;
254
  },
255
  ARRAY_FILTER_USE_KEY
256
  );
257
  }
258
+
259
+ public function optimize_fonts_tab()
260
+ {
261
+ $this->generate_tab(self::OMGF_SETTINGS_FIELD_OPTIMIZE, 'dashicons-performance', __('Optimize Fonts', $this->plugin_text_domain));
262
  }
263
+
264
  /**
265
  * Add Basic Settings Tab to Settings Screen.
266
  */
267
+ public function detection_settings_tab()
268
+ {
269
+ $this->generate_tab(self::OMGF_SETTINGS_FIELD_DETECTION, 'dashicons-search', __('Detection Settings', $this->plugin_text_domain));
270
  }
271
+
272
  /**
273
  * Add Advanced Settings Tab to Settings Screen.
274
  */
275
+ public function advanced_settings_tab()
276
+ {
277
+ $this->generate_tab(self::OMGF_SETTINGS_FIELD_ADVANCED, 'dashicons-admin-settings', __('Advanced Settings', $this->plugin_text_domain));
278
  }
279
+
280
  /**
281
  * @param $id
282
  * @param null $icon
283
  * @param null $label
284
  */
285
+ private function generate_tab($id, $icon = null, $label = null)
286
+ {
287
+ ?>
288
+ <a class="nav-tab dashicons-before <?= $icon; ?> <?= $this->active_tab == $id ? 'nav-tab-active' : ''; ?>" href="<?= $this->generate_tab_link($id); ?>">
289
  <?= $label; ?>
290
+ </a>
291
+ <?php
292
  }
293
+
294
  /**
295
  * @param $tab
296
  *
297
  * @return string
298
  */
299
+ private function generate_tab_link($tab)
300
+ {
301
+ return admin_url(self::OMGF_OPTIONS_GENERAL_PAGE_OPTIMIZE_WEBFONTS . "&tab=$tab");
302
  }
303
+
304
  /**
305
  *
306
  */
307
+ public function optimize_fonts_content()
308
+ {
309
+ $this->do_settings_content(self::OMGF_SETTINGS_FIELD_OPTIMIZE);
310
  }
311
+
312
  /**
313
  * Render Basic Settings content
314
  */
315
+ public function detection_settings_content()
316
+ {
317
+ $this->do_settings_content(self::OMGF_SETTINGS_FIELD_DETECTION);
318
  }
319
+
320
  /**
321
  * Render Advanced Settings content
322
  */
323
+ public function advanced_settings_content()
324
+ {
325
+ $this->do_settings_content(self::OMGF_SETTINGS_FIELD_ADVANCED);
326
  }
327
+
328
  /**
329
  * @param $field
330
  */
331
+ private function do_settings_content($field)
332
+ {
333
+ if ($this->active_tab != $field) {
334
  return;
335
  }
336
+ ?>
337
+ <form id="<?= $field; ?>-form" name="omgf-settings-form" method="post" action="<?= admin_url('options.php?tab=' . $this->active_tab); ?>" autocomplete="off">
 
338
  <?php
339
+ settings_fields($field);
340
+ do_settings_sections($field);
341
+
342
+ do_action('omgf_before_settings_form_settings');
343
+
344
+ echo apply_filters(str_replace('-', '_', $field) . '_content', '');
345
+
346
+ do_action('omgf_after_settings_form_settings');
347
+
348
+ submit_button($this->submit_button_text, 'primary', 'submit', false);
349
  ?>
350
+ <a id="omgf-empty" class="omgf-empty button-cancel"><?php _e('Empty Cache Directory', $this->plugin_text_domain); ?></a>
351
+ </form>
352
+ <?php
353
  }
354
+
355
  /**
356
  * @param $links
357
  *
358
  * @return mixed
359
  */
360
+ public function create_settings_link($links)
361
+ {
362
  $adminUrl = admin_url() . self::OMGF_OPTIONS_GENERAL_PAGE_OPTIMIZE_WEBFONTS;
363
+ $settingsLink = "<a href='$adminUrl'>" . __('Settings') . "</a>";
364
+ array_push($links, $settingsLink);
365
+
366
  return $links;
367
  }
368
  }
includes/admin/settings/class-advanced.php CHANGED
@@ -10,109 +10,116 @@
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_Advanced extends OMGF_Admin_Settings_Builder
20
  {
21
  /**
22
  * OMGF_Admin_Settings_Advanced constructor.
23
  */
24
- public function __construct () {
 
25
  parent::__construct();
26
-
27
- $this->title = __( 'Advanced Settings', $this->plugin_text_domain );
28
-
29
  // Open
30
- add_filter( 'omgf_advanced_settings_content', [ $this, 'do_title' ], 10 );
31
- add_filter( 'omgf_advanced_settings_content', [ $this, 'do_description' ], 15 );
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 );
39
- add_filter( 'omgf_advanced_settings_content', [ $this, 'do_uninstall' ], 110 );
40
-
41
  // Close
42
- add_filter( 'omgf_advanced_settings_content', [ $this, 'do_after' ], 200 );
43
  }
44
-
45
  /**
46
  * Description
47
  */
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
  }
55
-
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
-
82
  /**
83
  *
84
  */
85
- public function do_cache_uri () {
 
86
  $this->do_text(
87
- __( 'Serve font files from...', $this->plugin_text_domain ),
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
-
95
  /**
96
  *
97
  */
98
- public function do_relative_url () {
 
99
  $this->do_checkbox(
100
- __( 'Use Relative URLs?', $this->plugin_text_domain ),
101
  OMGF_Admin_Settings::OMGF_ADV_SETTING_RELATIVE_URL,
102
  OMGF_RELATIVE_URL,
103
- __( 'Use relative instead of absolute (full) URLs to generate the stylesheet.', $this->plugin_text_domain )
104
  );
105
  }
106
-
107
  /**
108
  *
109
  */
110
- public function do_uninstall () {
 
111
  $this->do_checkbox(
112
- __( 'Remove settings and files at uninstall?', $this->plugin_text_domain ),
113
  OMGF_Admin_Settings::OMGF_ADV_SETTING_UNINSTALL,
114
  OMGF_UNINSTALL,
115
- __( 'Warning! This will remove all settings and cached fonts upon plugin deletion.', $this->plugin_text_domain )
116
  );
117
  }
118
  }
10
  *
11
  * @package : OMGF
12
  * @author : Daan van den Bergh
13
+ * @copyright: (c) 2021 Daan van den Bergh
14
  * @url : https://daan.dev
15
  * * * * * * * * * * * * * * * * * * * */
16
 
17
+ defined('ABSPATH') || exit;
18
 
19
  class OMGF_Admin_Settings_Advanced extends OMGF_Admin_Settings_Builder
20
  {
21
  /**
22
  * OMGF_Admin_Settings_Advanced constructor.
23
  */
24
+ public function __construct()
25
+ {
26
  parent::__construct();
27
+
28
+ $this->title = __('Advanced Settings', $this->plugin_text_domain);
29
+
30
  // Open
31
+ add_filter('omgf_advanced_settings_content', [$this, 'do_title'], 10);
32
+ add_filter('omgf_advanced_settings_content', [$this, 'do_description'], 15);
33
+ add_filter('omgf_advanced_settings_content', [$this, 'do_before'], 20);
34
+
35
  // Settings
36
+ add_filter('omgf_advanced_settings_content', [$this, 'do_cache_dir'], 70);
37
+ add_filter('omgf_advanced_settings_content', [$this, 'do_cdn_url'], 80);
38
+ add_filter('omgf_advanced_settings_content', [$this, 'do_cache_uri'], 90);
39
+ add_filter('omgf_advanced_settings_content', [$this, 'do_relative_url'], 100);
40
+ add_filter('omgf_advanced_settings_content', [$this, 'do_uninstall'], 110);
41
+
42
  // Close
43
+ add_filter('omgf_advanced_settings_content', [$this, 'do_after'], 200);
44
  }
45
+
46
  /**
47
  * Description
48
  */
49
+ public function do_description()
50
+ {
51
+ ?>
52
+ <p>
53
+ <?= __('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); ?>
54
+ </p>
55
+ <?php
56
  }
57
+
58
  /**
59
  *
60
  */
61
+ public function do_cache_dir()
62
+ {
63
  $this->do_text(
64
+ __('Save font files to...', $this->plugin_text_domain),
65
  OMGF_Admin_Settings::OMGF_ADV_SETTING_CACHE_PATH,
66
+ __('e.g. /uploads/omgf', $this->plugin_text_domain),
67
  OMGF_CACHE_PATH,
68
+ __("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)
69
  );
70
  }
71
+
72
  /**
73
  *
74
  */
75
+ public function do_cdn_url()
76
+ {
77
  $this->do_text(
78
+ __('Serve fonts from CDN', $this->plugin_text_domain),
79
  OMGF_Admin_Settings::OMGF_ADV_SETTING_CDN_URL,
80
+ __('e.g. https://cdn.mydomain.com', $this->plugin_text_domain),
81
  OMGF_CDN_URL,
82
+ __("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)
83
  );
84
  }
85
+
86
  /**
87
  *
88
  */
89
+ public function do_cache_uri()
90
+ {
91
  $this->do_text(
92
+ __('Serve font files from...', $this->plugin_text_domain),
93
  OMGF_Admin_Settings::OMGF_ADV_SETTING_CACHE_URI,
94
+ __('e.g. /app/uploads/omgf', $this->plugin_text_domain),
95
  OMGF_CACHE_URI,
96
+ __('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)
97
  );
98
  }
99
+
100
  /**
101
  *
102
  */
103
+ public function do_relative_url()
104
+ {
105
  $this->do_checkbox(
106
+ __('Use Relative URLs?', $this->plugin_text_domain),
107
  OMGF_Admin_Settings::OMGF_ADV_SETTING_RELATIVE_URL,
108
  OMGF_RELATIVE_URL,
109
+ __('Use relative instead of absolute (full) URLs to generate the stylesheet.', $this->plugin_text_domain)
110
  );
111
  }
112
+
113
  /**
114
  *
115
  */
116
+ public function do_uninstall()
117
+ {
118
  $this->do_checkbox(
119
+ __('Remove settings and files at uninstall?', $this->plugin_text_domain),
120
  OMGF_Admin_Settings::OMGF_ADV_SETTING_UNINSTALL,
121
  OMGF_UNINSTALL,
122
+ __('Warning! This will remove all settings and cached fonts upon plugin deletion.', $this->plugin_text_domain)
123
  );
124
  }
125
  }
includes/admin/settings/class-builder.php CHANGED
@@ -10,70 +10,75 @@
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_Builder
20
  {
21
  /** @var string $plugin_text_domain */
22
  protected $plugin_text_domain = 'host-webfonts-local';
23
-
24
  /** @var $title */
25
  protected $title;
26
-
27
  /** @var $promo string */
28
  protected $promo;
29
-
30
  /**
31
- * Only sets the promo string on settings load.
32
- *
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
  /**
42
  *
43
  */
44
- public function do_promo () {
45
- if (apply_filters('apply_omgf_pro_promo', true)) {
46
- $this->promo = apply_filters('omgf_pro_promo', sprintf( __('<a href="%s" target="_blank">Upgrade to Pro</a> to enable this option.', $this->plugin_text_domain), OMGF_Admin_Settings::FFWP_WORDPRESS_PLUGINS_OMGF_PRO ));
47
- }
48
- }
49
-
 
50
  /**
51
  *
52
  */
53
- public function do_before () {
54
- ?>
55
- <table class="form-table">
 
56
  <?php
57
  }
58
-
59
  /**
60
  *
61
  */
62
- public function do_after () {
 
63
  ?>
64
- </table>
65
- <?php
66
  }
67
-
68
  /**
69
  *
70
  */
71
- public function do_title () {
72
- ?>
73
- <h3><?= $this->title ?></h3>
74
- <?php
 
75
  }
76
-
77
  /**
78
  * Generate radio setting
79
  *
@@ -85,25 +90,25 @@ class OMGF_Admin_Settings_Builder
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
  *
@@ -114,36 +119,37 @@ class OMGF_Admin_Settings_Builder
114
  * @param $description
115
  * @param bool $update_required
116
  */
117
- public function do_select ( $label, $name, $options, $selected, $description, $is_multiselect = false, $disabled = false ) {
118
- ?>
119
- <tr>
120
- <th scope="row">
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
  ?>
128
- <?php foreach ( $options as $option => $option_label ): ?>
129
- <?php
130
- if (is_array($selected)) {
131
- $is_selected = in_array($option, $selected);
132
- } else {
133
- $is_selected = $selected == $option;
134
- }
135
- ?>
136
- <option value="<?= $option; ?>" <?= $is_selected ? 'selected="selected"' : ''; ?>><?= $option_label; ?></option>
137
  <?php endforeach; ?>
138
- </select>
139
- <p class="description">
140
- <?= apply_filters( $name . '_setting_description', $description ); ?>
141
- </p>
142
- </td>
143
- </tr>
144
- <?php
145
  }
146
-
147
  /**
148
  * Generate number setting.
149
  *
@@ -152,20 +158,21 @@ class OMGF_Admin_Settings_Builder
152
  * @param $value
153
  * @param $description
154
  */
155
- public function do_number ( $label, $name, $value, $description, $min = 0 ) {
156
- ?>
157
- <tr valign="top">
158
- <th scope="row"><?= apply_filters( $name . '_setting_label', $label ); ?></th>
159
- <td>
160
- <input class="<?= str_replace( '_', '-', $name ); ?>" type="number" name="<?= $name; ?>" min="<?= $min; ?>" value="<?= $value; ?>"/>
161
- <p class="description">
162
- <?= apply_filters( $name . '_setting_description', $description ); ?>
163
- </p>
164
- </td>
165
- </tr>
166
- <?php
 
167
  }
168
-
169
  /**
170
  * Generate text setting.
171
  *
@@ -176,21 +183,21 @@ class OMGF_Admin_Settings_Builder
176
  * @param string $description
177
  * @param bool $update_required
178
  */
179
- public function do_text ( $label, $name, $placeholder, $value, $description = '', $update_required = false, $visible = true ) {
180
- ?>
181
- <tr class="<?= str_replace( '_', '-', $name ); ?>-row" <?= $visible ? '' : 'style="display: none;"'; ?>>
182
- <th scope="row"><?= apply_filters( $name . '_setting_label', $label ); ?> <?= $update_required ?: ''; ?></th>
183
- <td>
184
- <input class="<?= str_replace( '_', '-', $name ); ?>" type="text" name="<?= $name; ?>" placeholder="<?= $placeholder; ?>"
185
- value="<?= $value; ?>"/>
186
- <p class="description">
187
- <?= apply_filters( $name . 'setting_description', $description ); ?>
188
- </p>
189
- </td>
190
- </tr>
191
- <?php
192
  }
193
-
194
  /**
195
  * Generate checkbox setting.
196
  *
@@ -199,17 +206,18 @@ class OMGF_Admin_Settings_Builder
199
  * @param $checked
200
  * @param $description
201
  */
202
- public function do_checkbox ( $label, $name, $checked, $description, $disabled = false ) {
203
- ?>
204
- <tr>
205
- <th scope="row"><?= apply_filters( $name . '_setting_label', $label ); ?></th>
206
- <td>
207
- <label for="<?= $name; ?>">
208
- <input id="<?= $name; ?>" type="checkbox" <?= apply_filters( $name . '_setting_disabled', $disabled ) ? 'disabled' : ''; ?> class="<?= str_replace( '_', '-', $name ); ?>" name="<?= $name; ?>" <?= $checked == "on" ? 'checked = "checked"' : ''; ?> />
209
- <?= apply_filters( $name . '_setting_description', $description ); ?>
210
- </label>
211
- </td>
212
- </tr>
213
- <?php
 
214
  }
215
  }
10
  *
11
  * @package : OMGF
12
  * @author : Daan van den Bergh
13
+ * @copyright: (c) 2021 Daan van den Bergh
14
  * @url : https://daan.dev
15
  * * * * * * * * * * * * * * * * * * * */
16
 
17
+ defined('ABSPATH') || exit;
18
 
19
  class OMGF_Admin_Settings_Builder
20
  {
21
  /** @var string $plugin_text_domain */
22
  protected $plugin_text_domain = 'host-webfonts-local';
23
+
24
  /** @var $title */
25
  protected $title;
26
+
27
  /** @var $promo string */
28
  protected $promo;
29
+
30
  /**
31
+ * Only sets the promo string on settings load.
32
+ *
33
  * OMGF_Admin_Settings_Builder constructor.
34
  */
35
+ public function __construct()
36
+ {
37
+ add_filter('omgf_optimize_settings_content', [$this, 'do_promo']);
38
+ add_filter('omgf_detection_settings_content', [$this, 'do_promo']);
39
+ add_filter('omgf_advanced_settings_content', [$this, 'do_promo']);
40
+ }
41
+
42
  /**
43
  *
44
  */
45
+ public function do_promo()
46
+ {
47
+ if (apply_filters('apply_omgf_pro_promo', true)) {
48
+ $this->promo = apply_filters('omgf_pro_promo', sprintf(__('<a href="%s" target="_blank">Upgrade to Pro</a> to enable this option.', $this->plugin_text_domain), OMGF_Admin_Settings::FFWP_WORDPRESS_PLUGINS_OMGF_PRO));
49
+ }
50
+ }
51
+
52
  /**
53
  *
54
  */
55
+ public function do_before()
56
+ {
57
+ ?>
58
+ <table class="form-table">
59
  <?php
60
  }
61
+
62
  /**
63
  *
64
  */
65
+ public function do_after()
66
+ {
67
  ?>
68
+ </table>
69
+ <?php
70
  }
71
+
72
  /**
73
  *
74
  */
75
+ public function do_title()
76
+ {
77
+ ?>
78
+ <h3><?= $this->title ?></h3>
79
+ <?php
80
  }
81
+
82
  /**
83
  * Generate radio setting
84
  *
90
  */
91
  public function do_radio($label, $inputs, $name, $checked, $description)
92
  {
93
+ ?>
94
+ <tr>
95
+ <th scope="row"><?= $label; ?></th>
96
+ <td>
97
+ <?php foreach ($inputs as $option => $option_label) : ?>
98
+ <label>
99
+ <input type="radio" class="<?= str_replace('_', '-', $name . '_' . $option); ?>" name="<?= $name; ?>" value="<?= $option; ?>" <?= $option == $checked ? 'checked="checked"' : ''; ?> />
100
  <?= $option_label; ?>
101
+ </label>
102
+ <br />
103
  <?php endforeach; ?>
104
+ <p class="description">
105
  <?= $description; ?>
106
+ </p>
107
+ </td>
108
+ </tr>
109
+ <?php
110
  }
111
+
112
  /**
113
  * Generate select setting
114
  *
119
  * @param $description
120
  * @param bool $update_required
121
  */
122
+ public function do_select($label, $name, $options, $selected, $description, $is_multiselect = false, $disabled = false)
123
+ {
124
+ ?>
125
+ <tr>
126
+ <th scope="row">
127
+ <?= apply_filters($name . '_setting_label', $label); ?>
128
+ </th>
129
+ <td>
130
+ <select name="<?= $name; ?><?= $is_multiselect ? '[]' : ''; ?>" class="<?= str_replace('_', '-', $name); ?>" <?= $is_multiselect ? 'size="8" multiple="multiple"' : ''; ?> <?= apply_filters($name . '_setting_disabled', $disabled) ? 'disabled' : ''; ?>>
131
  <?php
132
+ $options = apply_filters($name . '_setting_options', $options);
133
  ?>
134
+ <?php foreach ($options as $option => $option_label) : ?>
135
+ <?php
136
+ if (is_array($selected)) {
137
+ $is_selected = in_array($option, $selected);
138
+ } else {
139
+ $is_selected = $selected == $option;
140
+ }
141
+ ?>
142
+ <option value="<?= $option; ?>" <?= $is_selected ? 'selected="selected"' : ''; ?>><?= $option_label; ?></option>
143
  <?php endforeach; ?>
144
+ </select>
145
+ <p class="description">
146
+ <?= apply_filters($name . '_setting_description', $description); ?>
147
+ </p>
148
+ </td>
149
+ </tr>
150
+ <?php
151
  }
152
+
153
  /**
154
  * Generate number setting.
155
  *
158
  * @param $value
159
  * @param $description
160
  */
161
+ public function do_number($label, $name, $value, $description, $min = 0)
162
+ {
163
+ ?>
164
+ <tr valign="top">
165
+ <th scope="row"><?= apply_filters($name . '_setting_label', $label); ?></th>
166
+ <td>
167
+ <input class="<?= str_replace('_', '-', $name); ?>" type="number" name="<?= $name; ?>" min="<?= $min; ?>" value="<?= $value; ?>" />
168
+ <p class="description">
169
+ <?= apply_filters($name . '_setting_description', $description); ?>
170
+ </p>
171
+ </td>
172
+ </tr>
173
+ <?php
174
  }
175
+
176
  /**
177
  * Generate text setting.
178
  *
183
  * @param string $description
184
  * @param bool $update_required
185
  */
186
+ public function do_text($label, $name, $placeholder, $value, $description = '', $update_required = false, $visible = true)
187
+ {
188
+ ?>
189
+ <tr class="<?= str_replace('_', '-', $name); ?>-row" <?= $visible ? '' : 'style="display: none;"'; ?>>
190
+ <th scope="row"><?= apply_filters($name . '_setting_label', $label); ?> <?= $update_required ?: ''; ?></th>
191
+ <td>
192
+ <input class="<?= str_replace('_', '-', $name); ?>" type="text" name="<?= $name; ?>" placeholder="<?= $placeholder; ?>" value="<?= $value; ?>" />
193
+ <p class="description">
194
+ <?= apply_filters($name . 'setting_description', $description); ?>
195
+ </p>
196
+ </td>
197
+ </tr>
198
+ <?php
199
  }
200
+
201
  /**
202
  * Generate checkbox setting.
203
  *
206
  * @param $checked
207
  * @param $description
208
  */
209
+ public function do_checkbox($label, $name, $checked, $description, $disabled = false)
210
+ {
211
+ ?>
212
+ <tr>
213
+ <th scope="row"><?= apply_filters($name . '_setting_label', $label); ?></th>
214
+ <td>
215
+ <label for="<?= $name; ?>">
216
+ <input id="<?= $name; ?>" type="checkbox" <?= apply_filters($name . '_setting_disabled', $disabled) ? 'disabled' : ''; ?> class="<?= str_replace('_', '-', $name); ?>" name="<?= $name; ?>" <?= $checked == "on" ? 'checked = "checked"' : ''; ?> />
217
+ <?= apply_filters($name . '_setting_description', $description); ?>
218
+ </label>
219
+ </td>
220
+ </tr>
221
+ <?php
222
  }
223
  }
includes/admin/settings/class-detection.php CHANGED
@@ -10,137 +10,144 @@
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' ) ? OMGF_PRO_ADVANCED_PROCESSING : 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
  }
10
  *
11
  * @package : OMGF
12
  * @author : Daan van den Bergh
13
+ * @copyright: (c) 2021 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
+ {
23
  parent::__construct();
24
+
25
+ $this->title = __('Google Fonts Detection Settings', $this->plugin_text_domain);
26
+
27
  // Open
28
+ add_filter('omgf_detection_settings_content', [$this, 'do_title'], 10);
29
+ add_filter('omgf_detection_settings_content', [$this, 'do_description'], 15);
30
+ add_filter('omgf_detection_settings_content', [$this, 'do_before'], 20);
31
+
32
  // Settings
33
+ add_filter('omgf_detection_settings_content', [$this, 'do_process_google_fonts'], 30);
34
+ add_filter('omgf_detection_settings_content', [$this, 'do_promo_advanced_processing'], 40);
35
+ add_filter('omgf_detection_settings_content', [$this, 'do_promo_fonts_processing'], 50);
36
+ add_filter('omgf_detection_settings_content', [$this, 'do_promo_process_resource_hints'], 60);
37
+
38
  // Close
39
+ add_filter('omgf_detection_settings_content', [$this, 'do_after'], 100);
40
  }
41
+
42
  /**
43
  * Description
44
  */
45
+ public function do_description()
46
+ {
47
+ ?>
48
+ <p>
49
+ <?= __('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); ?>
50
+ </p>
51
+ <p>
52
+ <?= 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), '#'); ?>
53
+ </p>
54
+ <?php
55
  }
56
+
57
  /**
58
  *
59
  */
60
+ public function do_promo_fonts_processing()
61
+ {
62
+ ?>
63
+ <tr>
64
+ <th scope="row"><?= __('Google Fonts Processing (Pro)', $this->plugin_text_domain); ?></th>
65
+ <td>
66
+ <fieldset id="" class="scheme-list">
67
+ <?php foreach ($this->fonts_processing_pro_options() as $name => $data) : ?>
68
  <?php
69
+ $checked = defined(strtoupper($name)) ? constant(strtoupper($name)) : false;
70
+ $disabled = apply_filters($name . '_setting_disabled', true) ? 'disabled' : '';
71
  ?>
72
+ <label for="<?= $name; ?>">
73
+ <input type="checkbox" name="<?= $name; ?>" <?= $checked ? 'checked="checked"' : ''; ?> <?= $disabled; ?> /><?= $data['label']; ?>
74
+ &nbsp;
75
+ </label>
76
  <?php endforeach; ?>
77
+ </fieldset>
78
+ <p class="description">
79
  <?= $this->promo; ?>
80
+ </p>
81
+ <ul>
82
+ <?php foreach ($this->fonts_processing_pro_options() as $name => $data) : ?>
83
+ <li><strong><?= $data['label']; ?></strong>: <?= $data['description']; ?></li>
84
  <?php endforeach; ?>
85
+ </ul>
86
+ </td>
87
+ </tr>
88
+ <?php
89
  }
90
+
91
  /**
92
  * @return array
93
  */
94
+ private function fonts_processing_pro_options()
95
+ {
96
  return [
97
  'omgf_pro_process_stylesheets' => [
98
+ 'label' => __('Process Stylesheets', $this->plugin_text_domain),
99
+ 'description' => __('Process stylesheets loaded from <code>fonts.googleapis.com</code> or <code>fonts.gstatic.com</code>.', $this->plugin_text_domain)
100
  ],
101
  'omgf_pro_process_inline_styles' => [
102
+ 'label' => __('Process Inline Styles', $this->plugin_text_domain),
103
+ 'description' => __('Process all <code>@font-face</code> and <code>@import</code> rules loading Google Fonts.', $this->plugin_text_domain)
104
  ],
105
  'omgf_pro_process_webfont_loader' => [
106
+ 'label' => __('Process Webfont Loader', $this->plugin_text_domain),
107
+ 'description' => __('Process <code>webfont.js</code> libraries and the corresponding configuration defining which Google Fonts to load.', $this->plugin_text_domain)
108
  ]
109
  ];
110
  }
111
+
112
  /**
113
  *
114
  */
115
+ public function do_promo_advanced_processing()
116
+ {
117
  $this->do_checkbox(
118
+ __('Advanced Processing (Pro)', $this->plugin_text_domain),
119
  'omgf_pro_advanced_processing',
120
+ defined('OMGF_PRO_ADVANCED_PROCESSING') ? OMGF_PRO_ADVANCED_PROCESSING : false,
121
+ __('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,
122
  true
123
  );
124
  }
125
+
126
  /**
127
  *
128
  */
129
+ public function do_promo_process_resource_hints()
130
+ {
131
  $this->do_checkbox(
132
+ __('Remove Resource Hints (Pro)', $this->plugin_text_domain),
133
  'omgf_pro_process_resource_hints',
134
+ defined('OMGF_PRO_PROCESS_RESOURCE_HINTS') ? OMGF_PRO_PROCESS_RESOURCE_HINTS : false,
135
+ __('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,
136
  true
137
  );
138
  }
139
+
140
  /**
141
  *
142
  */
143
+ public function do_process_google_fonts()
144
+ {
145
  $this->do_select(
146
+ __('Google Fonts Processing', $this->plugin_text_domain),
147
  OMGF_Admin_Settings::OMGF_DETECTION_SETTING_FONT_PROCESSING,
148
  OMGF_Admin_Settings::OMGF_FONT_PROCESSING_OPTIONS,
149
  OMGF_FONT_PROCESSING,
150
+ 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)
151
  );
152
  }
153
  }
includes/admin/settings/class-optimize.php CHANGED
@@ -10,311 +10,317 @@
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
- <div class="omgf-optimize-fonts-manage">
147
- <p>
148
 
149
- </p>
150
- <table>
151
- <thead>
152
- <tr>
153
- <td>&nbsp;</td>
154
- <th><?= __( 'Style', $this->plugin_text_domain ); ?></th>
155
- <th><?= __( 'Weight', $this->plugin_text_domain ); ?></th>
156
- <th class="preload"><?= __( 'Preload', $this->plugin_text_domain ); ?></th>
157
- <th class="unload"><?= __( 'Do not load', $this->plugin_text_domain ); ?></th>
158
- </tr>
159
- </thead>
160
- <?php
161
- $cache_handles = omgf_init()::cache_keys();
162
- ?>
163
- <?php foreach ( $this->optimized_fonts as $handle => $fonts ): ?>
164
- <?php
165
- if (!omgf_init()::get_cache_key($handle)) {
166
- $cache_handles[] = $handle;
167
- }
168
- ?>
169
- <tbody class="stylesheet" id="<?= $handle; ?>">
170
- <?php foreach ( $fonts as $font ): ?>
171
- <?php if (count($font->variants) <= 0) continue; ?>
172
- <th><?= $font->family; ?> <span class="handle">(<?= $handle; ?>)</span></th>
173
- <?php foreach ( $font->variants as $variant ): ?>
174
- <tr>
175
- <td></td>
176
- <?php
177
- $preload = get_option( OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_PRELOAD_FONTS )[ $handle ][ $font->id ][ $variant->id ] ?? '';
178
- $unload = get_option( OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_UNLOAD_FONTS )[ $handle ][ $font->id ][ $variant->id ] ?? '';
179
- $class = $handle . '-' . $font->id . '-' . $variant->id;
180
- ?>
181
- <td><?= $variant->fontStyle; ?></td>
182
- <td><?= $variant->fontWeight; ?></td>
183
- <td class="preload-<?= $class; ?>">
184
- <input data-handle="<?= $handle; ?>" data-font-id="<?= $font->id; ?>" autocomplete="off" type="checkbox" class="preload"
185
- name="<?= OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_PRELOAD_FONTS; ?>[<?= $handle; ?>][<?= $font->id; ?>][<?= $variant->id; ?>]"
186
- value="<?= $variant->id; ?>" <?= $preload ? 'checked="checked"' : ''; ?> <?= $unload ? 'disabled' : ''; ?> />
187
- </td>
188
- <td class="unload-<?= $class; ?>">
189
- <input data-handle="<?= $handle; ?>" data-font-id="<?= $font->id; ?>" autocomplete="off" type="checkbox" class="unload"
190
- name="<?= OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_UNLOAD_FONTS; ?>[<?= $handle; ?>][<?= $font->id; ?>][<?= $variant->id; ?>]"
191
- value="<?= $variant->id; ?>" <?= $unload ? 'checked="checked"' : ''; ?> <?= $preload ? 'disabled' : ''; ?> />
192
- </td>
193
- </tr>
194
- <?php endforeach; ?>
195
- <?php endforeach; ?>
196
- </tbody>
197
- <?php endforeach; ?>
198
- </table>
199
- <div class="omgf-optimize-fonts-tooltip">
200
- <p>
201
- <span class="dashicons-before dashicons-info-outline"></span>
202
- <?php if ( OMGF_OPTIMIZATION_MODE == 'manual' ): ?>
203
- <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>
204
- <?php else: ?>
205
  <?php
206
- $no_cache_param = '?omgf_optimize=' . substr( md5( microtime() ), rand( 0, 26 ), 5 );
 
 
207
  ?>
208
- <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>
209
- <?php endif; ?>
210
- </p>
211
- </div>
212
- <input type="hidden" name="<?= OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_OPTIMIZED_FONTS; ?>" value="<?= serialize( $this->optimized_fonts ); ?>"/>
213
- <input type="hidden" name="<?= OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_MANUAL_OPTIMIZE_URL; ?>" value="<?= OMGF_MANUAL_OPTIMIZE_URL; ?>"/>
214
- <input id="<?= OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_UNLOAD_STYLESHEETS; ?>" type="hidden"
215
- name="<?= OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_UNLOAD_STYLESHEETS; ?>" value="<?= OMGF_UNLOAD_STYLESHEETS; ?>"/>
216
- <input id="<?= OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_CACHE_KEYS; ?>" type="hidden"
217
- name="<?= OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_CACHE_KEYS; ?>" value="<?= implode(',', $cache_handles); ?>" />
218
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
219
  <?php
220
- }
221
-
222
- /**
223
- *
224
- */
225
- public function do_manual_template () {
 
226
  ?>
227
- <div class="omgf-optimize-fonts-manual" <?= OMGF_OPTIMIZATION_MODE == 'manual' ? '' : 'style="display: none;"'; ?>>
228
- <p>
229
- <?= 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 ); ?>
230
- </p>
231
- <div class="omgf-optimize-fonts-pros">
232
- <h3>
233
- <span class="dashicons-before dashicons-yes"></span> <?= __( 'Pros:', $this->plugin_text_domain ); ?>
234
- </h3>
235
- <ul>
236
- <li><?= __( 'A small performance boost, because no calls to OMGF\'s Download API are made in the frontend.', $this->plugin_text_domain ); ?></li>
237
- </ul>
238
- </div>
239
- <div class="omgf-optimize-fonts-cons">
240
- <h3>
241
- <span class="dashicons-before dashicons-no"></span> <?= __( 'Cons', $this->plugin_text_domain ); ?>
242
- </h3>
243
- <ul>
244
- <li><?= __( 'High maintenance if you use a lot of different fonts on different pages.', $this->plugin_text_domain ); ?></li>
245
- </ul>
246
- </div>
247
- <p>
248
- <?= __( '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 ); ?>
249
- </p>
250
- <label for="<?= OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_MANUAL_OPTIMIZE_URL; ?>">
251
- <?= __( 'URL to Scan', $this->plugin_text_domain ); ?>
252
- <input id="<?= OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_MANUAL_OPTIMIZE_URL; ?>" type="text"
253
- name="<?= OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_MANUAL_OPTIMIZE_URL; ?>" value="<?= OMGF_MANUAL_OPTIMIZE_URL; ?>"/>
254
- </label>
255
- <div class="omgf-optimize-fonts-tooltip">
256
- <p>
257
- <span class="dashicons-before dashicons-info-outline"></span>
258
- <em><?= __( 'This section will be populated with all captured fonts, font styles and available options after saving changes.', $this->plugin_text_domain ); ?></em>
259
- </p>
260
- </div>
261
- </div>
262
  <?php
263
- }
264
-
265
- /**
266
- *
267
- */
268
- public function do_automatic_template () {
 
269
  ?>
270
- <div class="omgf-optimize-fonts-automatic" <?= OMGF_OPTIMIZATION_MODE == 'auto' ? '' : 'style="display: none;"'; ?>>
271
- <p>
272
- <?= 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 ); ?>
273
- </p>
274
- <div class="omgf-optimize-fonts-pros">
275
- <h3>
276
- <span class="dashicons-before dashicons-yes"></span> <?= __( 'Pros:', $this->plugin_text_domain ); ?>
277
- </h3>
278
- <ul>
279
- <li><?= __( 'No maintenance.', $this->plugin_text_domain ); ?></li>
280
- </ul>
281
- </div>
282
- <div class="omgf-optimize-fonts-cons">
283
- <h3>
284
- <span class="dashicons-before dashicons-no"></span> <?= __( 'Cons', $this->plugin_text_domain ); ?>
285
- </h3>
286
- <ul>
287
- <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>
288
- </ul>
289
- </div>
290
- <div class="omgf-optimize-fonts-tooltip">
291
- <p>
292
- <span class="dashicons-before dashicons-info-outline"></span>
293
- <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>
294
- </p>
295
- </div>
296
- </div>
297
  <?php
298
- }
299
-
300
- /**
301
- *
302
- */
303
- public function close_optimize_fonts_container () {
 
304
  ?>
305
- </div>
306
- <?php
307
- }
308
-
309
- /**
310
- *
311
- */
312
- public function do_optimize_edit_roles () {
313
- $this->do_checkbox(
314
- __( 'Optimize fonts for logged in editors/administrators?', $this->plugin_text_domain ),
315
- OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_OPTIMIZE_EDIT_ROLES,
316
- OMGF_OPTIMIZE_EDIT_ROLES,
317
- __( 'Should only be disabled while debugging/testing, e.g. using a page builder or switching themes.', $this->plugin_text_domain )
318
- );
 
 
319
  }
320
- }
10
  *
11
  * @package : OMGF
12
  * @author : Daan van den Bergh
13
+ * @copyright: (c) 2021 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
+ {
29
  parent::__construct();
30
+
31
+ $this->title = __('Optimize Google Fonts', $this->plugin_text_domain);
32
+
33
+ add_filter('omgf_optimize_settings_content', [$this, 'do_title'], 10);
34
+ add_filter('omgf_optimize_settings_content', [$this, 'do_description'], 15);
35
+
36
+ add_filter('omgf_optimize_settings_content', [$this, 'do_before'], 20);
37
+ add_filter('omgf_optimize_settings_content', [$this, 'do_optimization_mode'], 30);
38
+ add_filter('omgf_optimize_settings_content', [$this, 'do_promo_combine_requests'], 40);
39
+ add_filter('omgf_optimize_settings_content', [$this, 'do_display_option'], 50);
40
+ add_filter('omgf_optimize_settings_content', [$this, 'do_promo_force_subsets'], 60);
41
+ add_filter('omgf_optimize_settings_content', [$this, 'do_after'], 100);
42
+
43
+ add_filter('omgf_optimize_settings_content', [$this, 'do_optimize_fonts_container'], 200);
44
+ add_filter('omgf_optimize_settings_content', [$this, 'do_optimize_fonts_contents'], 250);
45
+ add_filter('omgf_optimize_settings_content', [$this, 'close_optimize_fonts_container'], 300);
46
+
47
+ add_filter('omgf_optimize_settings_content', [$this, 'do_before'], 350);
48
+ add_filter('omgf_optimize_settings_content', [$this, 'do_optimize_edit_roles'], 375);
49
+ add_filter('omgf_optimize_settings_content', [$this, 'do_after'], 400);
50
  }
51
+
52
  /**
53
  *
54
  */
55
+ public function do_description()
56
+ {
57
+ ?>
58
+ <p>
59
+ <?= __('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); ?>
60
+ </p>
61
+ <?php
62
  }
63
+
64
+ public function do_optimization_mode()
65
+ {
66
  $this->do_radio(
67
+ __('Optimization Mode', $this->plugin_text_domain),
68
  OMGF_Admin_Settings::OMGF_OPTIMIZATION_MODE,
69
  OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_OPTIMIZATION_MODE,
70
  OMGF_OPTIMIZATION_MODE,
71
+ __('<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)
72
  );
73
  }
74
+
75
  /**
76
  *
77
  */
78
+ public function do_promo_combine_requests()
79
+ {
80
  $this->do_checkbox(
81
+ __('Combine & Dedupe Google Fonts (Pro)', $this->plugin_text_domain),
82
  'omgf_pro_combine_requests',
83
+ defined('OMGF_PRO_COMBINE_REQUESTS') ? true : false,
84
+ __('Combine and deduplicate multiple font requests into one request. This feature is always on in OMGF Pro.', $this->plugin_text_domain) . ' ' . $this->promo,
85
  true
86
  );
87
  }
88
+
89
  /**
90
  *
91
  */
92
+ public function do_display_option()
93
+ {
94
  $this->do_select(
95
+ __('Font-display option', $this->plugin_text_domain),
96
  OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_DISPLAY_OPTION,
97
  OMGF_Admin_Settings::OMGF_FONT_DISPLAY_OPTIONS,
98
  OMGF_DISPLAY_OPTION,
99
+ __('Select which font-display strategy to use. Defaults to Swap (recommended).', $this->plugin_text_domain)
100
  );
101
  }
102
+
103
  /**
104
  *
105
  */
106
+ public function do_promo_force_subsets()
107
+ {
108
  $this->do_select(
109
+ __('Force Subsets (Pro)', $this->plugin_text_domain),
110
  'omgf_pro_force_subsets',
111
  OMGF_Admin_Settings::OMGF_FORCE_SUBSETS_OPTIONS,
112
+ defined('OMGF_PRO_FORCE_SUBSETS') ? OMGF_PRO_FORCE_SUBSETS : [],
113
+ __('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,
114
  true,
115
  true
116
  );
117
  }
118
+
119
  /**
120
  *
121
  */
122
+ public function do_optimize_fonts_container()
123
+ {
124
+ ?>
125
+ <div class="omgf-optimize-fonts-container welcome-panel">
126
  <?php
127
  }
128
+
129
  /**
130
  *
131
  */
132
+ public function do_optimize_fonts_contents()
133
+ {
134
  $this->optimized_fonts = omgf_init()::optimized_fonts();
135
  ?>
136
+ <h3><?= $this->optimized_fonts ? 'Manage Optimized Google Fonts' : __('Are you ready to Optimize your Google Fonts?', $this->plugin_text_domain); ?></h3>
137
+ <?php if ($this->optimized_fonts) : ?>
138
+ <?= $this->do_optimized_fonts_manager(); ?>
139
+ <?php else : ?>
140
+ <div class="omgf-optimize-fonts-description">
141
+ <?php
142
+ $this->do_manual_template();
143
+ $this->do_automatic_template();
144
+ ?>
145
+ </div>
146
+ <?php endif;
147
+ }
 
 
 
 
 
 
 
 
148
 
149
+ /**
150
+ *
151
+ */
152
+ private function do_optimized_fonts_manager()
153
+ {
154
+ ?>
155
+ <div class="omgf-optimize-fonts-manage">
156
+ <p>
157
+
158
+ </p>
159
+ <table>
160
+ <thead>
161
+ <tr>
162
+ <td>&nbsp;</td>
163
+ <th><?= __('Style', $this->plugin_text_domain); ?></th>
164
+ <th><?= __('Weight', $this->plugin_text_domain); ?></th>
165
+ <th class="preload"><?= __('Preload', $this->plugin_text_domain); ?></th>
166
+ <th class="unload"><?= __('Do not load', $this->plugin_text_domain); ?></th>
167
+ </tr>
168
+ </thead>
169
+ <?php
170
+ $cache_handles = omgf_init()::cache_keys();
171
+ ?>
172
+ <?php foreach ($this->optimized_fonts as $handle => $fonts) : ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
173
  <?php
174
+ if (!omgf_init()::get_cache_key($handle)) {
175
+ $cache_handles[] = $handle;
176
+ }
177
  ?>
178
+ <tbody class="stylesheet" id="<?= $handle; ?>">
179
+ <?php foreach ($fonts as $font) : ?>
180
+ <?php if (count($font->variants) <= 0) continue; ?>
181
+ <th><?= $font->family; ?> <span class="handle">(<?= $handle; ?>)</span></th>
182
+ <?php foreach ($font->variants as $variant) : ?>
183
+ <tr>
184
+ <td></td>
185
+ <?php
186
+ $preload = get_option(OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_PRELOAD_FONTS)[$handle][$font->id][$variant->id] ?? '';
187
+ $unload = get_option(OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_UNLOAD_FONTS)[$handle][$font->id][$variant->id] ?? '';
188
+ $class = $handle . '-' . $font->id . '-' . $variant->id;
189
+ ?>
190
+ <td><?= $variant->fontStyle; ?></td>
191
+ <td><?= $variant->fontWeight; ?></td>
192
+ <td class="preload-<?= $class; ?>">
193
+ <input data-handle="<?= $handle; ?>" data-font-id="<?= $font->id; ?>" 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"' : ''; ?> <?= $unload ? 'disabled' : ''; ?> />
194
+ </td>
195
+ <td class="unload-<?= $class; ?>">
196
+ <input data-handle="<?= $handle; ?>" data-font-id="<?= $font->id; ?>" 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"' : ''; ?> <?= $preload ? 'disabled' : ''; ?> />
197
+ </td>
198
+ </tr>
199
+ <?php endforeach; ?>
200
+ <?php endforeach; ?>
201
+ </tbody>
202
+ <?php endforeach; ?>
203
+ </table>
204
+ <div class="omgf-optimize-fonts-tooltip">
205
+ <p>
206
+ <span class="dashicons-before dashicons-info-outline"></span>
207
+ <?php if (OMGF_OPTIMIZATION_MODE == 'manual') : ?>
208
+ <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>
209
+ <?php else : ?>
210
+ <?php
211
+ $no_cache_param = '?omgf_optimize=' . substr(md5(microtime()), rand(0, 26), 5);
212
+ ?>
213
+ <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>
214
+ <?php endif; ?>
215
+ </p>
216
+ </div>
217
+ <input type="hidden" name="<?= OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_OPTIMIZED_FONTS; ?>" value="<?= serialize($this->optimized_fonts); ?>" />
218
+ <input type="hidden" name="<?= OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_MANUAL_OPTIMIZE_URL; ?>" value="<?= OMGF_MANUAL_OPTIMIZE_URL; ?>" />
219
+ <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; ?>" />
220
+ <input id="<?= OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_CACHE_KEYS; ?>" type="hidden" name="<?= OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_CACHE_KEYS; ?>" value="<?= implode(',', $cache_handles); ?>" />
221
+ </div>
222
  <?php
223
+ }
224
+
225
+ /**
226
+ *
227
+ */
228
+ public function do_manual_template()
229
+ {
230
  ?>
231
+ <div class="omgf-optimize-fonts-manual" <?= OMGF_OPTIMIZATION_MODE == 'manual' ? '' : 'style="display: none;"'; ?>>
232
+ <p>
233
+ <?= 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); ?>
234
+ </p>
235
+ <div class="omgf-optimize-fonts-pros">
236
+ <h3>
237
+ <span class="dashicons-before dashicons-yes"></span> <?= __('Pros:', $this->plugin_text_domain); ?>
238
+ </h3>
239
+ <ul>
240
+ <li><?= __('A small performance boost, because no calls to OMGF\'s Download API are made in the frontend.', $this->plugin_text_domain); ?></li>
241
+ </ul>
242
+ </div>
243
+ <div class="omgf-optimize-fonts-cons">
244
+ <h3>
245
+ <span class="dashicons-before dashicons-no"></span> <?= __('Cons', $this->plugin_text_domain); ?>
246
+ </h3>
247
+ <ul>
248
+ <li><?= __('High maintenance if you use a lot of different fonts on different pages.', $this->plugin_text_domain); ?></li>
249
+ </ul>
250
+ </div>
251
+ <p>
252
+ <?= __('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); ?>
253
+ </p>
254
+ <label for="<?= OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_MANUAL_OPTIMIZE_URL; ?>">
255
+ <?= __('URL to Scan', $this->plugin_text_domain); ?>
256
+ <input id="<?= OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_MANUAL_OPTIMIZE_URL; ?>" type="text" name="<?= OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_MANUAL_OPTIMIZE_URL; ?>" value="<?= OMGF_MANUAL_OPTIMIZE_URL; ?>" />
257
+ </label>
258
+ <div class="omgf-optimize-fonts-tooltip">
259
+ <p>
260
+ <span class="dashicons-before dashicons-info-outline"></span>
261
+ <em><?= __('This section will be populated with all captured fonts, font styles and available options after saving changes.', $this->plugin_text_domain); ?></em>
262
+ </p>
263
+ </div>
264
+ </div>
 
265
  <?php
266
+ }
267
+
268
+ /**
269
+ *
270
+ */
271
+ public function do_automatic_template()
272
+ {
273
  ?>
274
+ <div class="omgf-optimize-fonts-automatic" <?= OMGF_OPTIMIZATION_MODE == 'auto' ? '' : 'style="display: none;"'; ?>>
275
+ <p>
276
+ <?= 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); ?>
277
+ </p>
278
+ <div class="omgf-optimize-fonts-pros">
279
+ <h3>
280
+ <span class="dashicons-before dashicons-yes"></span> <?= __('Pros:', $this->plugin_text_domain); ?>
281
+ </h3>
282
+ <ul>
283
+ <li><?= __('No maintenance.', $this->plugin_text_domain); ?></li>
284
+ </ul>
285
+ </div>
286
+ <div class="omgf-optimize-fonts-cons">
287
+ <h3>
288
+ <span class="dashicons-before dashicons-no"></span> <?= __('Cons', $this->plugin_text_domain); ?>
289
+ </h3>
290
+ <ul>
291
+ <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>
292
+ </ul>
293
+ </div>
294
+ <div class="omgf-optimize-fonts-tooltip">
295
+ <p>
296
+ <span class="dashicons-before dashicons-info-outline"></span>
297
+ <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>
298
+ </p>
299
+ </div>
300
+ </div>
301
  <?php
302
+ }
303
+
304
+ /**
305
+ *
306
+ */
307
+ public function close_optimize_fonts_container()
308
+ {
309
  ?>
310
+ </div>
311
+ <?php
312
+ }
313
+
314
+ /**
315
+ *
316
+ */
317
+ public function do_optimize_edit_roles()
318
+ {
319
+ $this->do_checkbox(
320
+ __('Optimize fonts for logged in editors/administrators?', $this->plugin_text_domain),
321
+ OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_OPTIMIZE_EDIT_ROLES,
322
+ OMGF_OPTIMIZE_EDIT_ROLES,
323
+ __('Should only be disabled while debugging/testing, e.g. using a page builder or switching themes.', $this->plugin_text_domain)
324
+ );
325
+ }
326
  }
 
includes/api/class-download.php CHANGED
@@ -10,444 +10,455 @@
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_API_Download extends WP_REST_Controller
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';
30
-
31
- /** @var string $rest_base */
32
- protected $rest_base = '/download/';
33
-
34
- /** @var string $handle */
35
- private $handle = '';
36
-
37
- /** @var string $path */
38
- private $path = '';
39
-
40
- /**
41
- *
42
- */
43
- public function register_routes () {
44
- foreach ( $this->endpoints as $endpoint ) {
45
- register_rest_route(
46
- $this->namespace,
47
- '/' . $this->rest_base . $endpoint,
48
- [
49
- [
50
- 'methods' => 'GET',
51
- 'callback' => [ $this, 'process' ],
52
- 'permission_callback' => [ $this, 'permissions_check' ]
53
- ],
54
- 'schema' => null,
55
- ]
56
- );
57
- }
58
- }
59
-
60
- /**
61
- * @return bool
62
- */
63
- public function permissions_check () {
64
- return true;
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 );
129
- $variant->ttf = $this->download( $variant->ttf, $filename );
130
- }
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
- $current_font = [ $original_handle => $fonts ];
139
- $optimized_fonts = omgf_init()::optimized_fonts();
140
-
141
- // At first run, simply override the optimized_fonts array.
142
- if ( empty( $optimized_fonts ) ) {
143
- $optimized_fonts = $current_font;
144
- // When a new font is detected, add it to the list.
145
- } elseif ( ! isset( $optimized_fonts[ $original_handle ] ) ) {
146
- $optimized_fonts = $optimized_fonts + $current_font;
147
- // Unload is probably used. Let's rewrite the variants still in use.
148
- } else {
149
- $optimized_fonts = $this->rewrite_variants( $optimized_fonts, $current_font );
150
- }
151
-
152
- update_option( OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_OPTIMIZED_FONTS, $optimized_fonts );
153
-
154
- // After downloading it, serve it.
155
- header( 'Content-Type: text/css' );
156
- header( "Content-Transfer-Encoding: Binary" );
157
- header( 'Content-Length: ' . filesize( $local_file ) );
158
- flush();
159
- readfile( $local_file );
160
- die();
161
- }
162
-
163
- /**
164
- * @param $variants
165
- * @param $unloaded_fonts
166
- * @param $font_id
167
- *
168
- * @return array
169
- */
170
- private function dequeue_unloaded_fonts ( $variants, $unloaded_fonts, $font_id ) {
171
- return array_filter(
172
- $variants,
173
- function ( $value ) use ( $unloaded_fonts, $font_id ) {
174
- if ( $value == '400' ) {
175
- // Sometimes the font is defined as 'regular', so we need to check both.
176
- return ! in_array( 'regular', $unloaded_fonts [ $font_id ] ) && ! in_array( $value, $unloaded_fonts [ $font_id ] );
177
- }
178
-
179
- return ! in_array( $value, $unloaded_fonts[ $font_id ] );
180
- }
181
- );
182
- }
183
-
184
- /**
185
- * Converts requests to OMGF's Download/CSS2 API to a format readable by the regular API.
186
- *
187
- * @param $request WP_Rest_Request
188
- */
189
- private function convert_css2 ( &$request ) {
190
- $query = $this->get_query_from_request();
191
- $params = explode( '&', $query );
192
- $font_families = [];
193
- $fonts = [];
194
-
195
- foreach ( $params as $param ) {
196
- if ( strpos( $param, 'family' ) === false ) {
197
- continue;
198
- }
199
-
200
- parse_str( $param, $parts );
201
-
202
- $font_families[] = $parts;
203
- }
204
-
205
- foreach ( $font_families as $font_family ) {
206
- list( $family, $weights ) = explode( ':', reset( $font_family ) );
207
-
208
- /**
209
- * @return array [ '300', '400', '500', etc. ]
210
- */
211
- $weights = explode( ';', substr( $weights, strpos( $weights, '@' ) + 1 ) );
212
-
213
- $fonts[] = $family . ':' . implode( ',', $weights );
214
- }
215
-
216
- $request->set_param( 'family', implode( '|', $fonts ) );
217
- }
218
-
219
- /**
220
- * Since Google Fonts' variable fonts API uses the same name for each parameter ('family') we need to parse the url manually.
221
- *
222
- * @return mixed
223
- */
224
- private function get_query_from_request () {
225
- return parse_url( $_SERVER['REQUEST_URI'] )['query'];
226
- }
227
-
228
- /**
229
- * @param $font_family
230
- * @param $url
231
- * @param $query
232
- *
233
- * @return mixed|void
234
- */
235
- private function grab_font_family ( $font_family, $url, $query ) {
236
- list( $family, $variants ) = explode( ':', $font_family );
237
- $family = strtolower( str_replace( ' ', '-', $family ) );
238
-
239
- $response = wp_remote_get(
240
- sprintf( $url, $family ) . '?' . http_build_query( $query )
241
- );
242
-
243
- $response_code = $response['response']['code'] ?? '';
244
-
245
- if ( $response_code !== 200 ) {
246
- $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 ) );
247
-
248
- OMGF_Admin_Notice::set_notice(
249
- $message,
250
- 'omgf_api_error',
251
- false,
252
- 'error'
253
- );
254
-
255
- return [];
256
- }
257
-
258
- if ( ! is_wp_error( $response ) && wp_remote_retrieve_response_code( $response ) == 200 ) {
259
- return json_decode( wp_remote_retrieve_body( $response ) );
260
- }
261
- }
262
-
263
- /**
264
- * @param $font_families
265
- * @param $font
266
- *
267
- * @return mixed
268
- */
269
- private function filter_font_families ( $font_families, $font ) {
270
- $font_request = array_filter(
271
- $font_families,
272
- function ( $value ) use ( $font ) {
273
- return strpos( $value, $font->family ) !== false;
274
- }
275
- );
276
-
277
- return reset( $font_request );
278
- }
279
-
280
- /**
281
- * @param $variants
282
- * @param $font
283
- *
284
- * @return array
285
- */
286
- private function process_variants ( $variants, $font ) {
287
- $variants = array_filter( explode( ',', $variants ) );
288
-
289
- // This means by default all fonts are requested, so we need to fill up the queue, before unloading the unwanted variants.
290
- if ( count( $variants ) == 0 ) {
291
- foreach ( $font->variants as $variant ) {
292
- $variants[] = $variant->id;
293
- }
294
- }
295
-
296
- return $variants;
297
- }
298
-
299
- /**
300
- * @param $available_variants
301
- * @param $wanted
302
- *
303
- * @return array
304
- */
305
- private function filter_variants ( $available_variants, $wanted ) {
306
- list ( $family, $variants ) = explode( ':', $wanted );
307
-
308
- if ( ! $variants ) {
309
- return $available_variants;
310
- }
311
-
312
- $variants = explode( ',', $variants );
313
-
314
- return array_filter(
315
- $available_variants,
316
- function ( $font ) use ( $variants ) {
317
- $id = $font->id;
318
-
319
- if ( $id == 'regular' || $id == '400' ) {
320
- return in_array( '400', $variants ) || in_array( 'regular', $variants );
321
- }
322
-
323
- if ( $id == 'italic' ) {
324
- return in_array( '400italic', $variants ) || in_array( 'italic', $variants );
325
- }
326
-
327
- return in_array( $id, $variants );
328
- }
329
- );
330
- }
331
-
332
- /**
333
- * @param $url
334
- * @param $filename
335
- *
336
- * @return string
337
- */
338
- private function download ( $url, $filename ) {
339
- if ( ! function_exists( 'download_url' ) ) {
340
- require_once ABSPATH . 'wp-admin/includes/file.php';
341
- }
342
-
343
- wp_mkdir_p( $this->path );
344
-
345
- $file = $this->path . '/' . $filename . '.' . pathinfo( $url, PATHINFO_EXTENSION );
346
- $file_uri = str_replace( WP_CONTENT_DIR, '', $file );
347
-
348
- if ( file_exists( $file ) ) {
349
- return content_url( $file_uri );
350
- }
351
-
352
- $tmp = download_url( $url );
353
- copy( $tmp, $file );
354
- @unlink( $tmp );
355
-
356
- return content_url( $file_uri );
357
- }
358
-
359
- /**
360
- * @param $fonts
361
- *
362
- * @return string
363
- */
364
- private function generate_stylesheet ( $fonts ) {
365
- $stylesheet = "/**\n * Auto Generated by OMGF\n * @author: Daan van den Bergh\n * @url: https://ffwp.dev\n */\n\n";
366
- $font_display = OMGF_DISPLAY_OPTION;
367
-
368
- foreach ( $fonts as $font ) {
369
- foreach ( $font->variants as $variant ) {
370
- $font_family = $variant->fontFamily;
371
- $font_style = $variant->fontStyle;
372
- $font_weight = $variant->fontWeight;
373
- $stylesheet .= "@font-face {\n";
374
- $stylesheet .= " font-family: $font_family;\n";
375
- $stylesheet .= " font-style: $font_style;\n";
376
- $stylesheet .= " font-weight: $font_weight;\n";
377
- $stylesheet .= " font-display: $font_display;\n";
378
- $stylesheet .= " src: url('" . $variant->eot . "');\n";
379
-
380
- $local_src = '';
381
-
382
- if ( is_array( $variant->local ) ) {
383
- foreach ( $variant->local as $local ) {
384
- $local_src .= "local('$local'), ";
385
- }
386
- }
387
-
388
- $stylesheet .= " src: $local_src\n";
389
-
390
- $font_src_url = isset( $variant->woff2 ) ? [ 'woff2' => $variant->woff2 ] : [];
391
- $font_src_url = $font_src_url + ( isset( $variant->woff ) ? [ 'woff' => $variant->woff ] : [] );
392
- $font_src_url = $font_src_url + ( isset( $variant->ttf ) ? [ 'ttf' => $variant->ttf ] : [] );
393
-
394
- $stylesheet .= $this->build_source_string( $font_src_url );
395
- $stylesheet .= "}\n";
396
- }
397
- }
398
-
399
- return $stylesheet;
400
- }
401
-
402
- /**
403
- * When unload is used, insert the cache key for the variants still in use.
404
- *
405
- * @param $stylesheets
406
- * @param $current_font
407
- *
408
- * @return mixed
409
- */
410
- private function rewrite_variants ( $stylesheets, $current_font ) {
411
- foreach ( $stylesheets as $stylesheet => &$fonts ) {
412
- foreach ( $fonts as $index => &$font ) {
413
- if ( empty( (array) $font->variants ) ) {
414
- continue;
415
- }
416
-
417
- foreach ( $font->variants as $variant_index => &$variant ) {
418
- $replace_variant = $current_font[ $stylesheet ][ $index ]->variants[ $variant_index ] ?? (object) [];
419
-
420
- if ( ! empty( (array) $replace_variant ) ) {
421
- $variant = $replace_variant;
422
- }
423
- }
424
- }
425
- }
426
-
427
- return $stylesheets;
428
- }
429
-
430
- /**
431
- * @param $sources
432
- * @param string $type
433
- * @param bool $end_semi_colon
434
- *
435
- * @return string
436
- */
437
- private function build_source_string ( $sources, $type = 'url', $end_semi_colon = true ) {
438
- $lastSrc = end( $sources );
439
- $source = '';
440
-
441
- foreach ( $sources as $format => $url ) {
442
- $source .= " $type('$url')" . ( ! is_numeric( $format ) ? " format('$format')" : '' );
443
-
444
- if ( $url === $lastSrc && $end_semi_colon ) {
445
- $source .= ";\n";
446
- } else {
447
- $source .= ",\n";
448
- }
449
- }
450
-
451
- return $source;
452
- }
 
 
 
 
 
 
 
 
 
 
 
453
  }
10
  *
11
  * @package : OMGF
12
  * @author : Daan van den Bergh
13
+ * @copyright: (c) 2021 Daan van den Bergh
14
  * @url : https://daan.dev
15
  * * * * * * * * * * * * * * * * * * * */
16
 
17
+ defined('ABSPATH') || exit;
18
 
19
  class OMGF_API_Download extends WP_REST_Controller
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 */
26
+ private $endpoints = ['css', 'css2'];
27
+
28
+ /** @var string */
29
+ protected $namespace = 'omgf/v1';
30
+
31
+ /** @var string */
32
+ protected $rest_base = '/download/';
33
+
34
+ /** @var string */
35
+ private $handle = '';
36
+
37
+ /** @var string */
38
+ private $path = '';
39
+
40
+ public function register_routes()
41
+ {
42
+ foreach ($this->endpoints as $endpoint) {
43
+ register_rest_route(
44
+ $this->namespace,
45
+ '/' . $this->rest_base . $endpoint,
46
+ [
47
+ [
48
+ 'methods' => 'GET',
49
+ 'callback' => [$this, 'process'],
50
+ 'permission_callback' => [$this, 'permissions_check']
51
+ ],
52
+ 'schema' => null,
53
+ ]
54
+ );
55
+ }
56
+ }
57
+
58
+ /**
59
+ * @return bool
60
+ */
61
+ public function permissions_check()
62
+ {
63
+ return true;
64
+ }
65
+
66
+ /**
67
+ * @param $request WP_Rest_Request
68
+ */
69
+ public function process($request)
70
+ {
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);
129
+ $variant->ttf = $this->download($variant->ttf, $filename);
130
+ }
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
+ $current_font = [$original_handle => $fonts];
139
+ $optimized_fonts = omgf_init()::optimized_fonts();
140
+
141
+ // At first run, simply override the optimized_fonts array.
142
+ if (empty($optimized_fonts)) {
143
+ $optimized_fonts = $current_font;
144
+ // When a new font is detected, add it to the list.
145
+ } elseif (!isset($optimized_fonts[$original_handle])) {
146
+ $optimized_fonts = $optimized_fonts + $current_font;
147
+ // Unload is probably used. Let's rewrite the variants still in use.
148
+ } else {
149
+ $optimized_fonts = $this->rewrite_variants($optimized_fonts, $current_font);
150
+ }
151
+
152
+ update_option(OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_OPTIMIZED_FONTS, $optimized_fonts);
153
+
154
+ // After downloading it, serve it.
155
+ header('Content-Type: text/css');
156
+ header('Content-Transfer-Encoding: Binary');
157
+ header('Content-Length: ' . filesize($local_file));
158
+ flush();
159
+ readfile($local_file);
160
+ die();
161
+ }
162
+
163
+ /**
164
+ * @param $variants
165
+ * @param $unloaded_fonts
166
+ * @param $font_id
167
+ *
168
+ * @return array
169
+ */
170
+ private function dequeue_unloaded_fonts($variants, $unloaded_fonts, $font_id)
171
+ {
172
+ return array_filter(
173
+ $variants,
174
+ function ($value) use ($unloaded_fonts, $font_id) {
175
+ if ($value == '400') {
176
+ // Sometimes the font is defined as 'regular', so we need to check both.
177
+ return !in_array('regular', $unloaded_fonts[$font_id]) && !in_array($value, $unloaded_fonts[$font_id]);
178
+ }
179
+
180
+ return !in_array($value, $unloaded_fonts[$font_id]);
181
+ }
182
+ );
183
+ }
184
+
185
+ /**
186
+ * Converts requests to OMGF's Download/CSS2 API to a format readable by the regular API.
187
+ *
188
+ * @param $request WP_Rest_Request
189
+ */
190
+ private function convert_css2(&$request)
191
+ {
192
+ $query = $this->get_query_from_request();
193
+ $params = explode('&', $query);
194
+ $font_families = [];
195
+ $fonts = [];
196
+
197
+ foreach ($params as $param) {
198
+ if (strpos($param, 'family') === false) {
199
+ continue;
200
+ }
201
+
202
+ parse_str($param, $parts);
203
+
204
+ $font_families[] = $parts;
205
+ }
206
+
207
+ foreach ($font_families as $font_family) {
208
+ list($family, $weights) = explode(':', reset($font_family));
209
+
210
+ /**
211
+ * @return array [ '300', '400', '500', etc. ]
212
+ */
213
+ $weights = explode(';', substr($weights, strpos($weights, '@') + 1));
214
+
215
+ $fonts[] = $family . ':' . implode(',', $weights);
216
+ }
217
+
218
+ $request->set_param('family', implode('|', $fonts));
219
+ }
220
+
221
+ /**
222
+ * Since Google Fonts' variable fonts API uses the same name for each parameter ('family') we need to parse the url manually.
223
+ *
224
+ * @return mixed
225
+ */
226
+ private function get_query_from_request()
227
+ {
228
+ return parse_url($_SERVER['REQUEST_URI'])['query'];
229
+ }
230
+
231
+ /**
232
+ * @param $font_family
233
+ * @param $url
234
+ * @param $query
235
+ *
236
+ * @return mixed|void
237
+ */
238
+ private function grab_font_family($font_family, $url, $query)
239
+ {
240
+ list($family, $variants) = explode(':', $font_family);
241
+ $family = strtolower(str_replace(' ', '-', $family));
242
+
243
+ $response = wp_remote_get(
244
+ sprintf($url, $family) . '?' . http_build_query($query)
245
+ );
246
+
247
+ $response_code = $response['response']['code'] ?? '';
248
+
249
+ if ($response_code !== 200) {
250
+ $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));
251
+
252
+ OMGF_Admin_Notice::set_notice(
253
+ $message,
254
+ 'omgf_api_error',
255
+ false,
256
+ 'error'
257
+ );
258
+
259
+ return [];
260
+ }
261
+
262
+ if (!is_wp_error($response) && wp_remote_retrieve_response_code($response) == 200) {
263
+ return json_decode(wp_remote_retrieve_body($response));
264
+ }
265
+ }
266
+
267
+ /**
268
+ * @param $font_families
269
+ * @param $font
270
+ *
271
+ * @return mixed
272
+ */
273
+ private function filter_font_families($font_families, $font)
274
+ {
275
+ $font_request = array_filter(
276
+ $font_families,
277
+ function ($value) use ($font) {
278
+ return strpos($value, $font->family) !== false;
279
+ }
280
+ );
281
+
282
+ return reset($font_request);
283
+ }
284
+
285
+ /**
286
+ * @param $variants
287
+ * @param $font
288
+ *
289
+ * @return array
290
+ */
291
+ private function process_variants($variants, $font)
292
+ {
293
+ $variants = array_filter(explode(',', $variants));
294
+
295
+ // This means by default all fonts are requested, so we need to fill up the queue, before unloading the unwanted variants.
296
+ if (count($variants) == 0) {
297
+ foreach ($font->variants as $variant) {
298
+ $variants[] = $variant->id;
299
+ }
300
+ }
301
+
302
+ return $variants;
303
+ }
304
+
305
+ /**
306
+ * @param $available_variants
307
+ * @param $wanted
308
+ *
309
+ * @return array
310
+ */
311
+ private function filter_variants($available_variants, $wanted)
312
+ {
313
+ list($family, $variants) = explode(':', $wanted);
314
+
315
+ if (!$variants) {
316
+ return $available_variants;
317
+ }
318
+
319
+ $variants = explode(',', $variants);
320
+
321
+ return array_filter(
322
+ $available_variants,
323
+ function ($font) use ($variants) {
324
+ $id = $font->id;
325
+
326
+ if ($id == 'regular' || $id == '400') {
327
+ return in_array('400', $variants) || in_array('regular', $variants);
328
+ }
329
+
330
+ if ($id == 'italic') {
331
+ return in_array('400italic', $variants) || in_array('italic', $variants);
332
+ }
333
+
334
+ return in_array($id, $variants);
335
+ }
336
+ );
337
+ }
338
+
339
+ /**
340
+ * @param $url
341
+ * @param $filename
342
+ *
343
+ * @return string
344
+ */
345
+ private function download($url, $filename)
346
+ {
347
+ if (!function_exists('download_url')) {
348
+ require_once ABSPATH . 'wp-admin/includes/file.php';
349
+ }
350
+
351
+ wp_mkdir_p($this->path);
352
+
353
+ $file = $this->path . '/' . $filename . '.' . pathinfo($url, PATHINFO_EXTENSION);
354
+ $file_uri = str_replace(WP_CONTENT_DIR, '', $file);
355
+
356
+ if (file_exists($file)) {
357
+ return content_url($file_uri);
358
+ }
359
+
360
+ $tmp = download_url($url);
361
+ copy($tmp, $file);
362
+ @unlink($tmp);
363
+
364
+ return content_url($file_uri);
365
+ }
366
+
367
+ /**
368
+ * @param $fonts
369
+ *
370
+ * @return string
371
+ */
372
+ private function generate_stylesheet($fonts)
373
+ {
374
+ $stylesheet = "/**\n * Auto Generated by OMGF\n * @author: Daan van den Bergh\n * @url: https://ffw.press\n */\n\n";
375
+ $font_display = OMGF_DISPLAY_OPTION;
376
+
377
+ foreach ($fonts as $font) {
378
+ foreach ($font->variants as $variant) {
379
+ $font_family = $variant->fontFamily;
380
+ $font_style = $variant->fontStyle;
381
+ $font_weight = $variant->fontWeight;
382
+ $stylesheet .= "@font-face {\n";
383
+ $stylesheet .= " font-family: $font_family;\n";
384
+ $stylesheet .= " font-style: $font_style;\n";
385
+ $stylesheet .= " font-weight: $font_weight;\n";
386
+ $stylesheet .= " font-display: $font_display;\n";
387
+ $stylesheet .= " src: url('" . $variant->eot . "');\n";
388
+
389
+ $local_src = '';
390
+
391
+ if (isset($variant->local) && is_array($variant->local)) {
392
+ foreach ($variant->local as $local) {
393
+ $local_src .= "local('$local'), ";
394
+ }
395
+ }
396
+
397
+ $stylesheet .= " src: $local_src\n";
398
+
399
+ $font_src_url = isset($variant->woff2) ? ['woff2' => $variant->woff2] : [];
400
+ $font_src_url = $font_src_url + (isset($variant->woff) ? ['woff' => $variant->woff] : []);
401
+ $font_src_url = $font_src_url + (isset($variant->ttf) ? ['ttf' => $variant->ttf] : []);
402
+
403
+ $stylesheet .= $this->build_source_string($font_src_url);
404
+ $stylesheet .= "}\n";
405
+ }
406
+ }
407
+
408
+ return $stylesheet;
409
+ }
410
+
411
+ /**
412
+ * When unload is used, insert the cache key for the variants still in use.
413
+ *
414
+ * @param $stylesheets
415
+ * @param $current_font
416
+ *
417
+ * @return mixed
418
+ */
419
+ private function rewrite_variants($stylesheets, $current_font)
420
+ {
421
+ foreach ($stylesheets as $stylesheet => &$fonts) {
422
+ foreach ($fonts as $index => &$font) {
423
+ if (empty((array) $font->variants)) {
424
+ continue;
425
+ }
426
+
427
+ foreach ($font->variants as $variant_index => &$variant) {
428
+ $replace_variant = $current_font[$stylesheet][$index]->variants[$variant_index] ?? (object) [];
429
+
430
+ if (!empty((array) $replace_variant)) {
431
+ $variant = $replace_variant;
432
+ }
433
+ }
434
+ }
435
+ }
436
+
437
+ return $stylesheets;
438
+ }
439
+
440
+ /**
441
+ * @param $sources
442
+ * @param string $type
443
+ * @param bool $end_semi_colon
444
+ *
445
+ * @return string
446
+ */
447
+ private function build_source_string($sources, $type = 'url', $end_semi_colon = true)
448
+ {
449
+ $lastSrc = end($sources);
450
+ $source = '';
451
+
452
+ foreach ($sources as $format => $url) {
453
+ $source .= " $type('$url')" . (!is_numeric($format) ? " format('$format')" : '');
454
+
455
+ if ($url === $lastSrc && $end_semi_colon) {
456
+ $source .= ";\n";
457
+ } else {
458
+ $source .= ",\n";
459
+ }
460
+ }
461
+
462
+ return $source;
463
+ }
464
  }
includes/class-admin.php CHANGED
@@ -10,27 +10,28 @@
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
20
  {
21
  const OMGF_ADMIN_JS_HANDLE = 'omgf-admin-js';
22
  const OMGF_ADMIN_CSS_HANDLE = 'omgf-admin-css';
23
-
24
  /** @var array $show_notice */
25
  private $show_notice = [];
26
-
27
  /** @var string $plugin_text_domain */
28
  private $plugin_text_domain = 'host-webfonts-local';
29
-
30
  /**
31
  * OMGF_Admin constructor.
32
  */
33
- public function __construct () {
 
34
  /**
35
  * Filterable list of options that require the cache to be emptied.
36
  */
@@ -43,66 +44,72 @@ class OMGF_Admin
43
  OMGF_Admin_Settings::OMGF_ADV_SETTING_CDN_URL
44
  ]
45
  );
46
-
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_cache_keys', [ $this, 'clean_up_cache' ], 10, 3 );
56
- add_filter( 'pre_update_option', [ $this, 'settings_changed' ], 10, 3 );
57
  }
58
-
59
  /**
60
  * Enqueues the necessary JS and CSS and passes options as a JS object.
61
  *
62
  * @param $hook
63
  */
64
- public function enqueue_admin_scripts ( $hook ) {
65
- wp_enqueue_script( self::OMGF_ADMIN_JS_HANDLE, plugin_dir_url( OMGF_PLUGIN_FILE ) . 'assets/js/omgf-admin.js', [ 'jquery' ], OMGF_STATIC_VERSION, true );
66
- wp_enqueue_style( self::OMGF_ADMIN_CSS_HANDLE, plugin_dir_url( OMGF_PLUGIN_FILE ) . 'assets/css/omgf-admin.css', [], OMGF_STATIC_VERSION );
 
67
  }
68
-
69
  /**
70
  * @param $name
71
  *
72
  * @return mixed
73
  */
74
- protected function get_template ( $name ) {
 
75
  return include OMGF_PLUGIN_DIR . 'templates/admin/block-' . $name . '.phtml';
76
  }
77
-
78
  /**
79
  * Add notice to admin screen.
80
  */
81
- public function print_notices () {
 
82
  OMGF_Admin_Notice::print_notices();
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
  /**
100
  * @return OMGF_Admin_Settings_Advanced
101
  */
102
- private function do_advanced_settings () {
 
103
  return new OMGF_Admin_Settings_Advanced();
104
  }
105
-
106
  /**
107
  * @param $old_value
108
  * @param $value
@@ -110,10 +117,11 @@ class OMGF_Admin
110
  *
111
  * @return mixed
112
  */
113
- public function decode_option ( $old_value, $value, $option_name ) {
 
114
  return $value;
115
  }
116
-
117
  /**
118
  * Triggered when unload settings is changed, cleans up old cache files.
119
  *
@@ -123,49 +131,51 @@ class OMGF_Admin
123
  * @param $value
124
  * @param $option_name
125
  */
126
- public function clean_up_cache ( $value, $old_value ) {
127
- if ( $old_value == $value ) {
 
128
  return $value;
129
  }
130
-
131
- if ( $old_value == null ) {
132
  return $value;
133
  }
134
-
135
- $cache_keys = explode( ',', $old_value );
136
-
137
- foreach ( $cache_keys as $key ) {
138
- $entries = array_filter( (array) glob( OMGF_FONTS_DIR . "/*$key" ) );
139
-
140
- foreach ( $entries as $entry ) {
141
- OMGF::delete( $entry );
142
  }
143
  }
144
-
145
  return $value;
146
  }
147
-
148
  /**
149
  * @param $new_value
150
  * @param $old_settings
151
  *
152
  * @return mixed
153
  */
154
- public function settings_changed ( $value, $option_name, $old_value ) {
155
- if ( ! in_array( $option_name, $this->show_notice ) ) {
 
156
  return $value;
157
  }
158
-
159
- if ( $value != $old_value ) {
160
  global $wp_settings_errors;
161
-
162
- if ( ! empty ( $wp_settings_errors ) ) {
163
  $wp_settings_errors = [];
164
  }
165
-
166
- 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' );
167
  }
168
-
169
  return $value;
170
  }
171
  }
10
  *
11
  * @package : OMGF
12
  * @author : Daan van den Bergh
13
+ * @copyright: (c) 2021 Daan van den Bergh
14
  * @url : https://daan.dev
15
  * * * * * * * * * * * * * * * * * * * */
16
 
17
+ defined('ABSPATH') || exit;
18
 
19
  class OMGF_Admin
20
  {
21
  const OMGF_ADMIN_JS_HANDLE = 'omgf-admin-js';
22
  const OMGF_ADMIN_CSS_HANDLE = 'omgf-admin-css';
23
+
24
  /** @var array $show_notice */
25
  private $show_notice = [];
26
+
27
  /** @var string $plugin_text_domain */
28
  private $plugin_text_domain = 'host-webfonts-local';
29
+
30
  /**
31
  * OMGF_Admin constructor.
32
  */
33
+ public function __construct()
34
+ {
35
  /**
36
  * Filterable list of options that require the cache to be emptied.
37
  */
44
  OMGF_Admin_Settings::OMGF_ADV_SETTING_CDN_URL
45
  ]
46
  );
47
+
48
+ add_action('admin_enqueue_scripts', [$this, 'enqueue_admin_scripts']);
49
+ add_action('admin_notices', [$this, 'print_notices']);
50
+
51
  $this->do_optimize_settings();
52
  $this->do_detection_settings();
53
  $this->do_advanced_settings();
54
+
55
+ add_filter('pre_update_option_omgf_optimized_fonts', [$this, 'decode_option'], 10, 3);
56
+ add_filter('pre_update_option_omgf_cache_keys', [$this, 'clean_up_cache'], 10, 3);
57
+ add_filter('pre_update_option', [$this, 'settings_changed'], 10, 3);
58
  }
59
+
60
  /**
61
  * Enqueues the necessary JS and CSS and passes options as a JS object.
62
  *
63
  * @param $hook
64
  */
65
+ public function enqueue_admin_scripts($hook)
66
+ {
67
+ wp_enqueue_script(self::OMGF_ADMIN_JS_HANDLE, plugin_dir_url(OMGF_PLUGIN_FILE) . 'assets/js/omgf-admin.js', ['jquery'], OMGF_STATIC_VERSION, true);
68
+ wp_enqueue_style(self::OMGF_ADMIN_CSS_HANDLE, plugin_dir_url(OMGF_PLUGIN_FILE) . 'assets/css/omgf-admin.css', [], OMGF_STATIC_VERSION);
69
  }
70
+
71
  /**
72
  * @param $name
73
  *
74
  * @return mixed
75
  */
76
+ protected function get_template($name)
77
+ {
78
  return include OMGF_PLUGIN_DIR . 'templates/admin/block-' . $name . '.phtml';
79
  }
80
+
81
  /**
82
  * Add notice to admin screen.
83
  */
84
+ public function print_notices()
85
+ {
86
  OMGF_Admin_Notice::print_notices();
87
  }
88
+
89
  /**
90
  * @return OMGF_Admin_Settings_Optimize
91
  */
92
+ private function do_optimize_settings()
93
+ {
94
  return new OMGF_Admin_Settings_Optimize();
95
  }
96
+
97
  /**
98
  * @return OMGF_Admin_Settings_Detection
99
  */
100
+ private function do_detection_settings()
101
+ {
102
  return new OMGF_Admin_Settings_Detection();
103
  }
104
+
105
  /**
106
  * @return OMGF_Admin_Settings_Advanced
107
  */
108
+ private function do_advanced_settings()
109
+ {
110
  return new OMGF_Admin_Settings_Advanced();
111
  }
112
+
113
  /**
114
  * @param $old_value
115
  * @param $value
117
  *
118
  * @return mixed
119
  */
120
+ public function decode_option($old_value, $value, $option_name)
121
+ {
122
  return $value;
123
  }
124
+
125
  /**
126
  * Triggered when unload settings is changed, cleans up old cache files.
127
  *
131
  * @param $value
132
  * @param $option_name
133
  */
134
+ public function clean_up_cache($value, $old_value)
135
+ {
136
+ if ($old_value == $value) {
137
  return $value;
138
  }
139
+
140
+ if ($old_value == null) {
141
  return $value;
142
  }
143
+
144
+ $cache_keys = explode(',', $old_value);
145
+
146
+ foreach ($cache_keys as $key) {
147
+ $entries = array_filter((array) glob(OMGF_FONTS_DIR . "/*$key"));
148
+
149
+ foreach ($entries as $entry) {
150
+ OMGF::delete($entry);
151
  }
152
  }
153
+
154
  return $value;
155
  }
156
+
157
  /**
158
  * @param $new_value
159
  * @param $old_settings
160
  *
161
  * @return mixed
162
  */
163
+ public function settings_changed($value, $option_name, $old_value)
164
+ {
165
+ if (!in_array($option_name, $this->show_notice)) {
166
  return $value;
167
  }
168
+
169
+ if ($value != $old_value) {
170
  global $wp_settings_errors;
171
+
172
+ if (!empty($wp_settings_errors)) {
173
  $wp_settings_errors = [];
174
  }
175
+
176
+ 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');
177
  }
178
+
179
  return $value;
180
  }
181
  }
includes/class-ajax.php CHANGED
@@ -10,47 +10,49 @@
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_AJAX
20
  {
21
  /** @var string $plugin_text_domain */
22
  private $plugin_text_domain = 'host-webfonts-local';
23
-
24
  /**
25
  * OMGF_AJAX constructor.
26
  */
27
- public function __construct () {
28
- add_action( 'wp_ajax_omgf_ajax_empty_dir', [ $this, 'empty_directory' ] );
 
29
  }
30
-
31
  /**
32
  * Empty cache directory.
33
  */
34
- public function empty_directory () {
 
35
  try {
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 ) {
52
  OMGF_Admin_Notice::set_notice(
53
- __( 'OMGF encountered an error while emptying the cache directory: ', $this->plugin_text_domain ) . $e->getMessage(),
54
  'omgf-cache-error',
55
  true,
56
  'error',
10
  *
11
  * @package : OMGF
12
  * @author : Daan van den Bergh
13
+ * @copyright: (c) 2021 Daan van den Bergh
14
  * @url : https://daan.dev
15
  * * * * * * * * * * * * * * * * * * * */
16
 
17
+ defined('ABSPATH') || exit;
18
 
19
  class OMGF_AJAX
20
  {
21
  /** @var string $plugin_text_domain */
22
  private $plugin_text_domain = 'host-webfonts-local';
23
+
24
  /**
25
  * OMGF_AJAX constructor.
26
  */
27
+ public function __construct()
28
+ {
29
+ add_action('wp_ajax_omgf_ajax_empty_dir', [$this, 'empty_directory']);
30
  }
31
+
32
  /**
33
  * Empty cache directory.
34
  */
35
+ public function empty_directory()
36
+ {
37
  try {
38
+ $entries = array_filter((array) glob(OMGF_FONTS_DIR . '/*'));
39
+
40
+ foreach ($entries as $entry) {
41
+ OMGF::delete($entry);
42
  }
43
+
44
  /**
45
  * Empty related options.
46
  */
47
+ delete_option(OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_OPTIMIZED_FONTS);
48
+ delete_option(OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_UNLOAD_FONTS);
49
+ delete_option(OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_PRELOAD_FONTS);
50
+ delete_option(OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_UNLOAD_STYLESHEETS);
51
+
52
+ OMGF_Admin_Notice::set_notice(__('Cache directory successfully emptied.', $this->plugin_text_domain));
53
+ } catch (\Exception $e) {
54
  OMGF_Admin_Notice::set_notice(
55
+ __('OMGF encountered an error while emptying the cache directory: ', $this->plugin_text_domain) . $e->getMessage(),
56
  'omgf-cache-error',
57
  true,
58
  'error',
includes/class-omgf.php CHANGED
@@ -10,195 +10,246 @@
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
20
  {
21
  /**
22
  * OMGF constructor.
23
  */
24
- public function __construct () {
 
25
  $this->define_constants();
26
-
27
- if ( is_admin() ) {
28
  $this->do_settings();
29
  $this->add_ajax_hooks();
30
  }
31
-
32
- if ( ! is_admin() ) {
33
  $this->do_frontend();
34
  }
35
-
36
- add_action( 'rest_api_init', [ $this, 'register_routes' ] );
37
- add_action( 'admin_init', [ $this, 'do_optimize' ] );
 
38
  }
39
-
40
  /**
41
  * Define constants.
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
- define( 'OMGF_CACHE_KEYS', esc_attr( get_option( OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_CACHE_KEYS, '' ) ) );
58
- }
59
-
 
60
  /**
61
  * @return array
62
  */
63
- public static function optimized_fonts () {
 
64
  static $optimized_fonts = [];
65
-
66
- if ( empty ( $optimized_fonts ) ) {
67
- $optimized_fonts = get_option( OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_OPTIMIZED_FONTS, [] );
68
  }
69
-
70
  return $optimized_fonts;
71
  }
72
-
73
  /**
74
  * @return array
75
  */
76
- public static function preloaded_fonts () {
 
77
  static $preloaded_fonts = [];
78
-
79
- if ( empty( $preloaded_fonts ) ) {
80
- $preloaded_fonts = get_option( OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_PRELOAD_FONTS, [] );
81
  }
82
-
83
  return $preloaded_fonts;
84
  }
85
-
86
  /**
87
  * @return array
88
  */
89
- public static function unloaded_fonts () {
 
90
  static $unloaded_fonts = [];
91
-
92
- if ( empty( $unloaded_fonts ) ) {
93
- $unloaded_fonts = get_option( OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_UNLOAD_FONTS, [] );
94
  }
95
-
96
  return $unloaded_fonts;
97
  }
98
-
99
  /**
100
  * @return array
101
  */
102
- public static function unloaded_stylesheets () {
 
103
  static $unloaded_stylesheets = [];
104
-
105
- if ( empty( $unloaded_stylesheets ) ) {
106
- $unloaded_stylesheets = explode( ',', get_option( OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_UNLOAD_STYLESHEETS, '' ) );
107
  }
108
-
109
- return array_filter( $unloaded_stylesheets );
110
  }
111
-
112
  /**
113
  * @return array
114
  */
115
- public static function cache_keys () {
 
116
  static $cache_keys = [];
117
-
118
- if ( empty( $cache_keys ) ) {
119
- $cache_keys = explode( ',', get_option( OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_CACHE_KEYS, '' ) );
120
  }
121
-
122
- return array_filter( $cache_keys );
123
  }
124
-
125
  /**
126
  * @param $handle
127
  *
128
  * @return string
129
  */
130
- public static function get_cache_key ($handle) {
 
131
  $cache_keys = self::cache_keys();
132
-
133
  foreach ($cache_keys as $index => $key) {
134
  if (strpos($key, $handle) !== false) {
135
  return $key;
136
  }
137
  }
138
-
139
  return '';
140
  }
141
-
142
  /**
143
  * @return OMGF_Admin_Settings
144
  */
145
- private function do_settings () {
 
146
  return new OMGF_Admin_Settings();
147
  }
148
-
149
  /**
150
  * @return OMGF_AJAX
151
  */
152
- private function add_ajax_hooks () {
 
153
  return new OMGF_AJAX();
154
  }
155
-
156
  /**
157
  * @return OMGF_Frontend_Functions
158
  */
159
- public function do_frontend () {
 
160
  return new OMGF_Frontend_Functions();
161
  }
162
-
163
  /**
164
  *
165
  */
166
- public function register_routes () {
 
167
  $proxy = new OMGF_API_Download();
168
  $proxy->register_routes();
169
  }
170
-
171
  /**
172
  * @return OMGF_Optimize
173
  */
174
- public function do_optimize () {
 
175
  return new OMGF_Optimize();
176
  }
177
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
178
  /**
179
  * @return OMGF_Uninstall
180
  * @throws ReflectionException
181
  */
182
- public static function do_uninstall () {
 
183
  return new OMGF_Uninstall();
184
  }
185
-
186
  /**
187
  * @param $entry
188
  */
189
- public static function delete ( $entry ) {
190
- if ( is_dir( $entry ) ) {
191
- $file = new \FilesystemIterator( $entry );
192
-
 
193
  // If dir is empty, valid() returns false.
194
- while ( $file->valid() ) {
195
- self::delete( $file->getPathName() );
196
  $file->next();
197
  }
198
-
199
- rmdir( $entry );
200
  } else {
201
- unlink( $entry );
202
  }
203
  }
204
  }
10
  *
11
  * @package : OMGF
12
  * @author : Daan van den Bergh
13
+ * @copyright: (c) 2021 Daan van den Bergh
14
  * @url : https://daan.dev
15
  * * * * * * * * * * * * * * * * * * * */
16
 
17
+ defined('ABSPATH') || exit;
18
 
19
  class OMGF
20
  {
21
  /**
22
  * OMGF constructor.
23
  */
24
+ public function __construct()
25
+ {
26
  $this->define_constants();
27
+
28
+ if (is_admin()) {
29
  $this->do_settings();
30
  $this->add_ajax_hooks();
31
  }
32
+
33
+ if (!is_admin()) {
34
  $this->do_frontend();
35
  }
36
+
37
+ add_action('rest_api_init', [$this, 'register_routes']);
38
+ add_action('admin_init', [$this, 'do_optimize']);
39
+ add_filter('content_url', [$this, 'rewrite_url'], 10, 2);
40
  }
41
+
42
  /**
43
  * Define constants.
44
  */
45
+ public function define_constants()
46
+ {
47
+ define('OMGF_SITE_URL', 'https://daan.dev');
48
+ define('OMGF_OPTIMIZATION_MODE', esc_attr(get_option(OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_OPTIMIZATION_MODE, 'manual')));
49
+ define('OMGF_MANUAL_OPTIMIZE_URL', esc_attr(get_option(OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_MANUAL_OPTIMIZE_URL, site_url())));
50
+ define('OMGF_FONT_PROCESSING', esc_attr(get_option(OMGF_Admin_Settings::OMGF_DETECTION_SETTING_FONT_PROCESSING, 'replace')));
51
+ define('OMGF_DISPLAY_OPTION', esc_attr(get_option(OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_DISPLAY_OPTION, 'swap')) ?: 'swap');
52
+ define('OMGF_OPTIMIZE_EDIT_ROLES', esc_attr(get_option(OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_OPTIMIZE_EDIT_ROLES, 'on')));
53
+ define('OMGF_CACHE_PATH', esc_attr(get_option(OMGF_Admin_Settings::OMGF_ADV_SETTING_CACHE_PATH)) ?: '/uploads/omgf');
54
+ define('OMGF_CACHE_URI', esc_attr(get_option(OMGF_Admin_Settings::OMGF_ADV_SETTING_CACHE_URI)) ?: '');
55
+ define('OMGF_RELATIVE_URL', esc_attr(get_option(OMGF_Admin_Settings::OMGF_ADV_SETTING_RELATIVE_URL)));
56
+ define('OMGF_CDN_URL', esc_attr(get_option(OMGF_Admin_Settings::OMGF_ADV_SETTING_CDN_URL)));
57
+ define('OMGF_FONTS_DIR', WP_CONTENT_DIR . OMGF_CACHE_PATH);
58
+ define('OMGF_UNINSTALL', esc_attr(get_option(OMGF_Admin_Settings::OMGF_ADV_SETTING_UNINSTALL)));
59
+ define('OMGF_UNLOAD_STYLESHEETS', esc_attr(get_option(OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_UNLOAD_STYLESHEETS, '')));
60
+ define('OMGF_CACHE_KEYS', esc_attr(get_option(OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_CACHE_KEYS, '')));
61
+ }
62
+
63
  /**
64
  * @return array
65
  */
66
+ public static function optimized_fonts()
67
+ {
68
  static $optimized_fonts = [];
69
+
70
+ if (empty($optimized_fonts)) {
71
+ $optimized_fonts = get_option(OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_OPTIMIZED_FONTS, []);
72
  }
73
+
74
  return $optimized_fonts;
75
  }
76
+
77
  /**
78
  * @return array
79
  */
80
+ public static function preloaded_fonts()
81
+ {
82
  static $preloaded_fonts = [];
83
+
84
+ if (empty($preloaded_fonts)) {
85
+ $preloaded_fonts = get_option(OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_PRELOAD_FONTS, []);
86
  }
87
+
88
  return $preloaded_fonts;
89
  }
90
+
91
  /**
92
  * @return array
93
  */
94
+ public static function unloaded_fonts()
95
+ {
96
  static $unloaded_fonts = [];
97
+
98
+ if (empty($unloaded_fonts)) {
99
+ $unloaded_fonts = get_option(OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_UNLOAD_FONTS, []);
100
  }
101
+
102
  return $unloaded_fonts;
103
  }
104
+
105
  /**
106
  * @return array
107
  */
108
+ public static function unloaded_stylesheets()
109
+ {
110
  static $unloaded_stylesheets = [];
111
+
112
+ if (empty($unloaded_stylesheets)) {
113
+ $unloaded_stylesheets = explode(',', get_option(OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_UNLOAD_STYLESHEETS, ''));
114
  }
115
+
116
+ return array_filter($unloaded_stylesheets);
117
  }
118
+
119
  /**
120
  * @return array
121
  */
122
+ public static function cache_keys()
123
+ {
124
  static $cache_keys = [];
125
+
126
+ if (empty($cache_keys)) {
127
+ $cache_keys = explode(',', get_option(OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_CACHE_KEYS, ''));
128
  }
129
+
130
+ return array_filter($cache_keys);
131
  }
132
+
133
  /**
134
  * @param $handle
135
  *
136
  * @return string
137
  */
138
+ public static function get_cache_key($handle)
139
+ {
140
  $cache_keys = self::cache_keys();
141
+
142
  foreach ($cache_keys as $index => $key) {
143
  if (strpos($key, $handle) !== false) {
144
  return $key;
145
  }
146
  }
147
+
148
  return '';
149
  }
150
+
151
  /**
152
  * @return OMGF_Admin_Settings
153
  */
154
+ private function do_settings()
155
+ {
156
  return new OMGF_Admin_Settings();
157
  }
158
+
159
  /**
160
  * @return OMGF_AJAX
161
  */
162
+ private function add_ajax_hooks()
163
+ {
164
  return new OMGF_AJAX();
165
  }
166
+
167
  /**
168
  * @return OMGF_Frontend_Functions
169
  */
170
+ public function do_frontend()
171
+ {
172
  return new OMGF_Frontend_Functions();
173
  }
174
+
175
  /**
176
  *
177
  */
178
+ public function register_routes()
179
+ {
180
  $proxy = new OMGF_API_Download();
181
  $proxy->register_routes();
182
  }
183
+
184
  /**
185
  * @return OMGF_Optimize
186
  */
187
+ public function do_optimize()
188
+ {
189
  return new OMGF_Optimize();
190
  }
191
+
192
+ /**
193
+ * @param $url
194
+ * @param $path
195
+ *
196
+ * @return mixed
197
+ */
198
+ public function rewrite_url($url, $path)
199
+ {
200
+ /**
201
+ * Exit early if this isn't requested by OMGF.
202
+ */
203
+ if (strpos($url, OMGF_CACHE_PATH) === false) {
204
+ return $url;
205
+ }
206
+
207
+ /**
208
+ * If Relative URLs is enabled, overwrite URL with Path and continue execution.
209
+ */
210
+ if (OMGF_RELATIVE_URL) {
211
+ $content_dir = str_replace(site_url(), '', content_url());
212
+
213
+ $url = $content_dir . $path;
214
+ }
215
+
216
+ if (OMGF_CDN_URL) {
217
+ $url = str_replace(site_url(), OMGF_CDN_URL, $url);
218
+ }
219
+
220
+ if (OMGF_CACHE_URI) {
221
+ $url = str_replace(OMGF_CACHE_PATH, OMGF_CACHE_URI, $url);
222
+ }
223
+
224
+ return $url;
225
+ }
226
+
227
  /**
228
  * @return OMGF_Uninstall
229
  * @throws ReflectionException
230
  */
231
+ public static function do_uninstall()
232
+ {
233
  return new OMGF_Uninstall();
234
  }
235
+
236
  /**
237
  * @param $entry
238
  */
239
+ public static function delete($entry)
240
+ {
241
+ if (is_dir($entry)) {
242
+ $file = new \FilesystemIterator($entry);
243
+
244
  // If dir is empty, valid() returns false.
245
+ while ($file->valid()) {
246
+ self::delete($file->getPathName());
247
  $file->next();
248
  }
249
+
250
+ rmdir($entry);
251
  } else {
252
+ unlink($entry);
253
  }
254
  }
255
  }
includes/class-optimize.php CHANGED
@@ -10,149 +10,148 @@
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_CACHE_KEYS, $_POST[ OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_CACHE_KEYS ] );
43
- update_option( OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_UNLOAD_FONTS, $_POST[ OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_UNLOAD_FONTS ] );
44
- update_option( OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_PRELOAD_FONTS, $_POST[ OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_PRELOAD_FONTS ] );
45
- update_option( OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_UNLOAD_STYLESHEETS, $_POST[ OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_UNLOAD_STYLESHEETS ] );
46
-
47
- if ( $this->optimization_mode == 'manual' ) {
48
- $this->run_manual();
49
- }
50
-
51
- if ( $this->optimization_mode == 'auto' ) {
52
- $this->run_auto();
53
- }
54
- }
55
-
56
- /**
57
- *
58
- */
59
- private function run_manual () {
60
- $url = esc_url_raw( $_POST[ OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_MANUAL_OPTIMIZE_URL ] );
61
-
62
- $front_html = wp_remote_get(
63
- $this->no_cache_optimize_url( $url ),
64
- [
65
- 'timeout' => 30
66
- ]
67
- );
68
-
69
- if ( is_wp_error( $front_html ) ) {
70
- $this->frontend_fetch_failed( $front_html );
71
- }
72
-
73
- $urls = [];
74
- $document = new DOMDocument();
75
- @$document->loadHtml( wp_remote_retrieve_body( $front_html ) );
76
-
77
- foreach ( $document->getElementsByTagName( 'link' ) as $link ) {
78
- /** @var $link DOMElement */
79
- if ( $link->hasAttribute( 'href' ) && strpos( $link->getAttribute( 'href' ), '/omgf/v1/download/' ) ) {
80
- $urls[] = $link->getAttribute( 'href' );
81
- }
82
- }
83
-
84
- if ( empty( $urls ) ) {
85
- $this->no_urls_found();
86
- }
87
-
88
- foreach ( $urls as $url ) {
89
- $download = wp_remote_get(
90
- $this->no_cache_optimize_url( $url ),
91
- [
92
- 'timeout' => 30
93
- ]
94
- );
95
-
96
- if ( is_wp_error( $download ) ) {
97
- $this->download_failed( $download );
98
- }
99
- }
100
-
101
- $this->optimization_succeeded();
102
- }
103
-
104
- /**
105
- *
106
- */
107
- private function optimization_succeeded () {
108
- add_settings_error( 'general', 'omgf_optimization_success', __( 'Optimization completed successfully.' ), 'success' );
109
-
110
- OMGF_Admin_Notice::set_notice(
111
- __('If you\'re using any 3rd party optimization plugins (e.g. WP Rocket, Autoptimize, W3 Total Cache, etc.) make sure to flush their caches for OMGF\'s optimizations to take effect.', $this->plugin_text_domain),
112
- 'omgf-cache-notice',
113
- false,
114
- 'warning'
115
- );
116
- }
117
-
118
- /**
119
- * @param $download WP_Error
120
- */
121
- private function download_failed ( $download ) {
122
- 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' );
123
- }
124
-
125
- /**
126
- * @param $front_html WP_Error
127
- */
128
- private function frontend_fetch_failed ( $front_html ) {
129
- 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' );
130
- }
131
-
132
- /**
133
- *
134
- */
135
- private function no_urls_found () {
136
- add_settings_error( 'general', 'omgf_no_urls_found', __( 'No (additional) Google Fonts found to optimize.', $this->plugin_text_domain ), 'info' );
137
- }
138
-
139
- /**
140
- *
141
- */
142
- private function run_auto () {
143
- OMGF_Admin_Notice::set_notice(
144
- __( 'OMGF Optimization is silently running in the background. After visiting a few pages, return here to manage the captured Google Fonts.', $this->plugin_text_domain ),
145
- 'omgf-auto-running',
146
- false
147
- );
148
- }
149
-
150
- /**
151
- * @param $url
152
- *
153
- * @return string
154
- */
155
- private function no_cache_optimize_url ( $url ) {
156
- return add_query_arg( [ 'omgf_optimize' => 1, 'nocache' => substr( md5( microtime() ), rand( 0, 26 ), 5 ) ], $url );
157
- }
158
  }
10
  *
11
  * @package : OMGF
12
  * @author : Daan van den Bergh
13
+ * @copyright: (c) 2021 Daan van den Bergh
14
  * @url : https://daan.dev
15
  * * * * * * * * * * * * * * * * * * * */
16
 
17
+ defined('ABSPATH') || exit;
18
 
19
  class OMGF_Optimize
20
  {
21
+ /** @var string */
22
+ private $plugin_text_domain = 'host-webfonts-local';
23
+
24
+ /** @var mixed|string */
25
+ private $optimization_mode = '';
26
+
27
+ /**
28
+ * OMGF_Optimize constructor.
29
+ */
30
+ public function __construct()
31
+ {
32
+ $option_page = $_POST['option_page'] ?? '';
33
+ $this->optimization_mode = $_POST[OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_OPTIMIZATION_MODE] ?? '';
34
+
35
+ if (
36
+ OMGF_Admin_Settings::OMGF_SETTINGS_FIELD_OPTIMIZE != $option_page
37
+ && !$this->optimization_mode
38
+ ) {
39
+ return;
40
+ }
41
+
42
+ // Will die when it fails.
43
+ check_admin_referer('omgf-optimize-settings-options');
44
+
45
+ update_option(OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_CACHE_KEYS, $_POST[OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_CACHE_KEYS] ?? '');
46
+ update_option(OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_UNLOAD_FONTS, $_POST[OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_UNLOAD_FONTS] ?? '');
47
+ update_option(OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_PRELOAD_FONTS, $_POST[OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_PRELOAD_FONTS] ?? '');
48
+ update_option(OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_UNLOAD_STYLESHEETS, $_POST[OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_UNLOAD_STYLESHEETS] ?? '');
49
+
50
+ if ('manual' == $this->optimization_mode) {
51
+ $this->run_manual();
52
+ }
53
+
54
+ if ('auto' == $this->optimization_mode) {
55
+ $this->run_auto();
56
+ }
57
+ }
58
+
59
+ private function run_manual()
60
+ {
61
+ $url = esc_url_raw($_POST[OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_MANUAL_OPTIMIZE_URL]);
62
+
63
+ $front_html = wp_remote_get(
64
+ $this->no_cache_optimize_url($url),
65
+ [
66
+ 'timeout' => 30,
67
+ ]
68
+ );
69
+
70
+ if (is_wp_error($front_html)) {
71
+ $this->frontend_fetch_failed($front_html);
72
+ }
73
+
74
+ $urls = [];
75
+ $document = new DOMDocument();
76
+ libxml_use_internal_errors(true);
77
+ @$document->loadHtml(wp_remote_retrieve_body($front_html));
78
+
79
+ foreach ($document->getElementsByTagName('link') as $link) {
80
+ /** @var $link DOMElement */
81
+ if ($link->hasAttribute('href') && strpos($link->getAttribute('href'), '/omgf/v1/download/')) {
82
+ $urls[] = $link->getAttribute('href');
83
+ }
84
+ }
85
+
86
+ if (empty($urls)) {
87
+ $this->no_urls_found();
88
+ }
89
+
90
+ foreach ($urls as $url) {
91
+ $download = wp_remote_get(
92
+ $this->no_cache_optimize_url($url),
93
+ [
94
+ 'timeout' => 30
95
+ ]
96
+ );
97
+
98
+ if (is_wp_error($download)) {
99
+ $this->download_failed($download);
100
+ }
101
+ }
102
+
103
+ $this->optimization_succeeded();
104
+ }
105
+
106
+ private function optimization_succeeded()
107
+ {
108
+ add_settings_error('general', 'omgf_optimization_success', __('Optimization completed successfully.'), 'success');
109
+
110
+ OMGF_Admin_Notice::set_notice(
111
+ __('If you\'re using any 3rd party optimization plugins (e.g. WP Rocket, Autoptimize, W3 Total Cache, etc.) make sure to flush their caches for OMGF\'s optimizations to take effect.', $this->plugin_text_domain),
112
+ 'omgf-cache-notice',
113
+ false,
114
+ 'warning'
115
+ );
116
+ }
117
+
118
+ /**
119
+ * @param $download WP_Error
120
+ */
121
+ private function download_failed($download)
122
+ {
123
+ 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');
124
+ }
125
+
126
+ /**
127
+ * @param $front_html WP_Error
128
+ */
129
+ private function frontend_fetch_failed($front_html)
130
+ {
131
+ 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');
132
+ }
133
+
134
+ private function no_urls_found()
135
+ {
136
+ add_settings_error('general', 'omgf_no_urls_found', sprintf(__('No (additional) Google Fonts found to optimize. If you believe this is an error, please refer to the %stroubleshooting%s section of the documentation for possible solutions.', $this->plugin_text_domain), '<a href="https://ffw.press/docs/omgf-pro/troubleshooting">', '</a>'), 'info');
137
+ }
138
+
139
+ private function run_auto()
140
+ {
141
+ OMGF_Admin_Notice::set_notice(
142
+ __('OMGF Optimization is silently running in the background. After visiting a few pages, return here to manage the captured Google Fonts.', $this->plugin_text_domain),
143
+ 'omgf-auto-running',
144
+ false
145
+ );
146
+ }
147
+
148
+ /**
149
+ * @param $url
150
+ *
151
+ * @return string
152
+ */
153
+ private function no_cache_optimize_url($url)
154
+ {
155
+ return add_query_arg(['omgf_optimize' => 1, 'nocache' => substr(md5(microtime()), rand(0, 26), 5)], $url);
156
+ }
 
157
  }
includes/class-uninstall.php CHANGED
@@ -10,7 +10,7 @@
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
 
10
  *
11
  * @package : OMGF
12
  * @author : Daan van den Bergh
13
+ * @copyright: (c) 2021 Daan van den Bergh
14
  * @url : https://daan.dev
15
  * * * * * * * * * * * * * * * * * * * */
16
 
includes/frontend/class-functions.php CHANGED
@@ -10,210 +10,185 @@
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_Frontend_Functions
20
  {
21
  const OMGF_STYLE_HANDLE = 'omgf-fonts';
22
-
23
  /** @var bool $do_optimize */
24
  private $do_optimize;
25
-
26
  /**
27
  * OMGF_Frontend_Functions constructor.
28
  */
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
-
37
  /**
38
  * Should we optimize for logged in editors/administrators?
39
  *
40
  * @return bool
41
  */
42
- private function maybe_optimize_fonts () {
43
- if ( ! OMGF_OPTIMIZE_EDIT_ROLES && current_user_can( 'edit_pages' ) ) {
 
44
  return false;
45
  }
46
-
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
  * TODO: When setting all preloads at once (different stylesheet handles) combined with unloads, not all URLs are rewritten with their cache keys properly.
86
  * When configured handle by handle, it works fine. PHP multi-threading issues?
87
  */
88
- public function add_preloads () {
89
- $preloaded_fonts = omgf_init()::preloaded_fonts();
90
-
91
- if ( ! $preloaded_fonts ) {
 
92
  return;
93
  }
94
-
95
- $stylesheets = omgf_init()::optimized_fonts();
96
-
97
- foreach ( $stylesheets as $stylesheet => $fonts ) {
98
- foreach ( $fonts as $font ) {
99
- $preloads_stylesheet = $preloaded_fonts [ $stylesheet ] ?? [];
100
-
101
- if ( ! in_array( $font->id, array_keys( $preloads_stylesheet ) ) ) {
 
 
102
  continue;
103
  }
104
-
105
  $font_id = $font->id;
106
  $preload_variants = array_filter(
107
  $font->variants,
108
- function ( $variant ) use ( $preloads_stylesheet, $font_id ) {
109
- return in_array( $variant->id, $preloads_stylesheet[ $font_id ] );
110
  }
111
  );
112
-
113
- foreach ( $preload_variants as $variant ) {
114
  $url = $variant->woff2;
115
- echo "<link id='omgf-preload' rel='preload' href='$url' as='font' type='font/woff2' crossorigin />\n";
 
116
  }
117
  }
118
  }
119
  }
120
-
121
  /**
122
  * Check if the Remove Google Fonts option is enabled.
123
  */
124
- public function process_fonts () {
125
- if ( ! $this->do_optimize ) {
 
126
  return;
127
  }
128
-
129
- if ( is_admin() ) {
130
  return;
131
  }
132
-
133
- if ( apply_filters( 'omgf_pro_advanced_processing_enabled', false ) ) {
134
  return;
135
  }
136
-
137
- switch ( OMGF_FONT_PROCESSING ) {
138
  case 'remove':
139
- add_action( 'wp_print_styles', [ $this, 'remove_registered_fonts' ], PHP_INT_MAX - 500 );
140
  break;
141
  default:
142
- add_action( 'wp_print_styles', [ $this, 'replace_registered_fonts' ], PHP_INT_MAX - 500 );
143
  }
144
  }
145
-
146
  /**
147
  * This function contains a nice little hack, to avoid messing with potential dependency issues. We simply set the source to an empty string!
148
  */
149
- public function remove_registered_fonts () {
 
150
  global $wp_styles;
151
-
152
  $registered = $wp_styles->registered;
153
- $fonts = apply_filters( 'omgf_auto_remove', $this->detect_registered_google_fonts( $registered ) );
154
-
155
- foreach ( $fonts as $handle => $font ) {
156
- $wp_styles->registered [ $handle ]->src = '';
157
  }
158
  }
159
-
160
  /**
161
  * Retrieve stylesheets from Google Fonts' API and modify the stylesheet for local storage.
162
  */
163
- public function replace_registered_fonts () {
 
164
  global $wp_styles;
165
-
166
  $registered = $wp_styles->registered;
167
- $fonts = apply_filters( 'omgf_auto_replace', $this->detect_registered_google_fonts( $registered ) );
168
  $unloaded_stylesheets = omgf_init()::unloaded_stylesheets();
169
  $unloaded_fonts = omgf_init()::unloaded_fonts();
170
-
171
- foreach ( $fonts as $handle => $font ) {
172
  // If this stylesheet has been marked for unload, empty the src and skip out early.
173
- if ( in_array( $handle, $unloaded_stylesheets ) ) {
174
- $wp_styles->registered[ $handle ]->src = '';
175
-
176
  continue;
177
  }
178
-
179
  $updated_handle = $handle;
180
-
181
- if ( $unloaded_fonts ) {
182
  $updated_handle = omgf_init()::get_cache_key($handle);
183
  }
184
-
185
  $cached_file = OMGF_CACHE_PATH . '/' . $updated_handle . "/$updated_handle.css";
186
-
187
- if ( file_exists( WP_CONTENT_DIR . $cached_file ) ) {
188
- $wp_styles->registered[ $handle ]->src = content_url( $cached_file );
189
-
190
  continue;
191
  }
192
-
193
- if ( OMGF_OPTIMIZATION_MODE == 'auto' || ( OMGF_OPTIMIZATION_MODE == 'manual' && isset( $_GET['omgf_optimize'] ) ) ) {
194
- $api_url = str_replace( [ 'http:', 'https:' ], '', site_url( '/wp-json/omgf/v1/download/' ) );
195
  $protocol = '';
196
-
197
- if ( substr( $font->src, 0, 2 ) == '//' ) {
198
  $protocol = 'https:';
199
  }
200
-
201
- $wp_styles->registered[ $handle ]->src = $protocol . str_replace( '//fonts.googleapis.com/', $api_url, $font->src ) . "&handle=$updated_handle&original_handle=$handle";
202
  }
203
  }
204
  }
205
-
206
  /**
207
  * @param $registered_styles
208
  *
209
  * @return array
210
  */
211
- private function detect_registered_google_fonts ( $registered_styles ) {
 
212
  return array_filter(
213
  $registered_styles,
214
- function ( $contents ) {
215
- return strpos( $contents->src, 'fonts.googleapis.com/css' ) !== false
216
- || strpos( $contents->src, 'fonts.gstatic.com' ) !== false;
217
  }
218
  );
219
  }
10
  *
11
  * @package : OMGF
12
  * @author : Daan van den Bergh
13
+ * @copyright: (c) 2021 Daan van den Bergh
14
  * @url : https://daan.dev
15
  * * * * * * * * * * * * * * * * * * * */
16
 
17
+ defined('ABSPATH') || exit;
18
 
19
  class OMGF_Frontend_Functions
20
  {
21
  const OMGF_STYLE_HANDLE = 'omgf-fonts';
22
+
23
  /** @var bool $do_optimize */
24
  private $do_optimize;
25
+
26
  /**
27
  * OMGF_Frontend_Functions constructor.
28
  */
29
+ public function __construct()
30
+ {
31
  $this->do_optimize = $this->maybe_optimize_fonts();
32
+
33
+ add_action('wp_head', [$this, 'add_preloads'], 3);
34
+ add_action('wp_print_styles', [$this, 'process_fonts'], PHP_INT_MAX - 1000);
 
35
  }
36
+
37
  /**
38
  * Should we optimize for logged in editors/administrators?
39
  *
40
  * @return bool
41
  */
42
+ private function maybe_optimize_fonts()
43
+ {
44
+ if (!OMGF_OPTIMIZE_EDIT_ROLES && current_user_can('edit_pages')) {
45
  return false;
46
  }
47
+
48
  return true;
49
  }
50
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  /**
52
  * TODO: When setting all preloads at once (different stylesheet handles) combined with unloads, not all URLs are rewritten with their cache keys properly.
53
  * When configured handle by handle, it works fine. PHP multi-threading issues?
54
  */
55
+ public function add_preloads()
56
+ {
57
+ $preloaded_fonts = apply_filters('omgf_frontend_preloaded_fonts', omgf_init()::preloaded_fonts());
58
+
59
+ if (!$preloaded_fonts) {
60
  return;
61
  }
62
+
63
+ $stylesheets = apply_filters('omgf_frontend_optimized_fonts', omgf_init()::optimized_fonts());
64
+
65
+ $i = 0;
66
+
67
+ foreach ($stylesheets as $stylesheet => $fonts) {
68
+ foreach ($fonts as $font) {
69
+ $preloads_stylesheet = $preloaded_fonts[$stylesheet] ?? [];
70
+
71
+ if (!in_array($font->id, array_keys($preloads_stylesheet))) {
72
  continue;
73
  }
74
+
75
  $font_id = $font->id;
76
  $preload_variants = array_filter(
77
  $font->variants,
78
+ function ($variant) use ($preloads_stylesheet, $font_id) {
79
+ return in_array($variant->id, $preloads_stylesheet[$font_id]);
80
  }
81
  );
82
+
83
+ foreach ($preload_variants as $variant) {
84
  $url = $variant->woff2;
85
+ echo "<link id='omgf-preload-$i' rel='preload' href='$url' as='font' type='font/woff2' crossorigin />\n";
86
+ $i++;
87
  }
88
  }
89
  }
90
  }
91
+
92
  /**
93
  * Check if the Remove Google Fonts option is enabled.
94
  */
95
+ public function process_fonts()
96
+ {
97
+ if (!$this->do_optimize) {
98
  return;
99
  }
100
+
101
+ if (is_admin()) {
102
  return;
103
  }
104
+
105
+ if (apply_filters('omgf_pro_advanced_processing_enabled', false)) {
106
  return;
107
  }
108
+
109
+ switch (OMGF_FONT_PROCESSING) {
110
  case 'remove':
111
+ add_action('wp_print_styles', [$this, 'remove_registered_fonts'], PHP_INT_MAX - 500);
112
  break;
113
  default:
114
+ add_action('wp_print_styles', [$this, 'replace_registered_fonts'], PHP_INT_MAX - 500);
115
  }
116
  }
117
+
118
  /**
119
  * This function contains a nice little hack, to avoid messing with potential dependency issues. We simply set the source to an empty string!
120
  */
121
+ public function remove_registered_fonts()
122
+ {
123
  global $wp_styles;
124
+
125
  $registered = $wp_styles->registered;
126
+ $fonts = apply_filters('omgf_auto_remove', $this->detect_registered_google_fonts($registered));
127
+
128
+ foreach ($fonts as $handle => $font) {
129
+ $wp_styles->registered[$handle]->src = '';
130
  }
131
  }
132
+
133
  /**
134
  * Retrieve stylesheets from Google Fonts' API and modify the stylesheet for local storage.
135
  */
136
+ public function replace_registered_fonts()
137
+ {
138
  global $wp_styles;
139
+
140
  $registered = $wp_styles->registered;
141
+ $fonts = apply_filters('omgf_auto_replace', $this->detect_registered_google_fonts($registered));
142
  $unloaded_stylesheets = omgf_init()::unloaded_stylesheets();
143
  $unloaded_fonts = omgf_init()::unloaded_fonts();
144
+
145
+ foreach ($fonts as $handle => $font) {
146
  // If this stylesheet has been marked for unload, empty the src and skip out early.
147
+ if (in_array($handle, $unloaded_stylesheets)) {
148
+ $wp_styles->registered[$handle]->src = '';
149
+
150
  continue;
151
  }
152
+
153
  $updated_handle = $handle;
154
+
155
+ if ($unloaded_fonts) {
156
  $updated_handle = omgf_init()::get_cache_key($handle);
157
  }
158
+
159
  $cached_file = OMGF_CACHE_PATH . '/' . $updated_handle . "/$updated_handle.css";
160
+
161
+ if (file_exists(WP_CONTENT_DIR . $cached_file)) {
162
+ $wp_styles->registered[$handle]->src = content_url($cached_file);
163
+
164
  continue;
165
  }
166
+
167
+ if (OMGF_OPTIMIZATION_MODE == 'auto' || (OMGF_OPTIMIZATION_MODE == 'manual' && isset($_GET['omgf_optimize']))) {
168
+ $api_url = str_replace(['http:', 'https:'], '', home_url('/wp-json/omgf/v1/download/'));
169
  $protocol = '';
170
+
171
+ if (substr($font->src, 0, 2) == '//') {
172
  $protocol = 'https:';
173
  }
174
+
175
+ $wp_styles->registered[$handle]->src = $protocol . str_replace('//fonts.googleapis.com/', $api_url, $font->src) . "&handle=$updated_handle&original_handle=$handle";
176
  }
177
  }
178
  }
179
+
180
  /**
181
  * @param $registered_styles
182
  *
183
  * @return array
184
  */
185
+ private function detect_registered_google_fonts($registered_styles)
186
+ {
187
  return array_filter(
188
  $registered_styles,
189
+ function ($contents) {
190
+ return strpos($contents->src, 'fonts.googleapis.com/css') !== false
191
+ || strpos($contents->src, 'fonts.gstatic.com') !== false;
192
  }
193
  );
194
  }
readme.md CHANGED
@@ -17,7 +17,7 @@ After installing the plugin, OMGF runs silently in the background and captures a
17
 
18
  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.
19
 
20
- 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/).
21
 
22
  ### Features
23
  - Automatically replace registered/enqueued Google Fonts in `wp_head()` with local copies,
@@ -37,7 +37,7 @@ Everything in the free version, plus:
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
17
 
18
  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.
19
 
20
+ 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://ffw.press/wordpress/omgf-expert-configuration/).
21
 
22
  ### Features
23
  - Automatically replace registered/enqueued Google Fonts in `wp_head()` with local copies,
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://ffw.press/docs/omgf-pro/) | [Purchase OMGF Pro](https://ffw.press/wordpress/omgf-pro/)**
41
 
42
 
43
  ## Installation
readme.txt CHANGED
@@ -2,8 +2,8 @@
2
  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.2.4
7
  Requires PHP: 7.0
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
@@ -29,7 +29,7 @@ In *Automatic* Mode, OMGF runs silently in the background and captures any reque
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,
@@ -49,7 +49,7 @@ Everything in the free version, plus:
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/) | [Tested Plugins & Themes](https://ffwp.dev/docs/omgf-pro/troubleshooting/compatibility/)*
53
 
54
  == Installation ==
55
 
@@ -81,7 +81,7 @@ This could be for several reasons:
81
 
82
  = Does this plugin remove resource hints, e.g. preconnect, preload or dns-prefetch? =
83
 
84
- No, to automatically remove resource hints pointing to fonts.googleapis.com or fonts.gstatic.com, [upgrade to OMGF Pro](https://ffwp.dev/wordpress/omgf-pro/).
85
 
86
  = Can I serve the fonts from my CDN? =
87
 
@@ -89,7 +89,7 @@ Yes, you can. Enter the url of your CDN and empty OMGF's cache directory.
89
 
90
  = I have Google Fonts Processing set to Replace/Remove but the fonts from fonts.gstatic.com|fonts.googleapis.com are still loaded. What's going on? =
91
 
92
- The free version of OMGF removes any fonts that are loaded in the conventional way: wp_enqueue_scripts(). If it doesn't work for you, you're theme or plugins using other methods to load Google Fonts, e.g. in the footer, WebFont Loader, etc. [Upgrade to OMGF Pro](https://ffwp.dev/wordpress/omgf-pro/) to automatically replace these fonts with a locally hosted version.
93
 
94
  = Does this plugin edit template files? =
95
 
@@ -97,7 +97,7 @@ No, it does not. It creates a CSS Stylesheet which will be automatically added t
97
 
98
  = The stylesheet isn't loaded? What's going on? =
99
 
100
- The free version of OMGF enqueues the stylesheet into WordPress' head using wp_enqueue_scripts(). If the stylesheet isn't loaded, this probably means your theme isn't implementing wp_head() correctly. [Upgrade to OMGF Pro](https://ffwp.dev/wordpress/omgf-pro/) to automatically add the stylesheet into WordPress' head.
101
 
102
  = Does this plugin support Multi Site? I'm getting CORS errors! =
103
 
@@ -122,6 +122,13 @@ No, not yet. But I will definitely try to make it compatible in the future!
122
 
123
  == Changelog ==
124
 
 
 
 
 
 
 
 
125
  = 4.2.4 | December 8th, 2020 =
126
  * Cache keys are now fixed values instead of dynamically generated. This fixes the bug where preloads wouldn't load properly when combined with unloaded fonts of the same stylesheet.
127
  * **IMPORTANT**: To fix any bugs with preloads/unloads, emptying the cache directory is required.
2
  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.6
6
+ Stable tag: 4.2.5
7
  Requires PHP: 7.0
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
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://ffw.press/wordpress/omgf-expert-configuration/).
33
 
34
  = Features =
35
  - Automatically replace registered/enqueued Google Fonts in wp_head() with local copies,
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://ffw.press/wordpress/omgf-pro/) | [Documentation](https://ffw.press/docs/omgf-pro/) | [Tested Plugins & Themes](https://ffw.press/docs/omgf-pro/troubleshooting/compatibility/)*
53
 
54
  == Installation ==
55
 
81
 
82
  = Does this plugin remove resource hints, e.g. preconnect, preload or dns-prefetch? =
83
 
84
+ No, to automatically remove resource hints pointing to fonts.googleapis.com or fonts.gstatic.com, [upgrade to OMGF Pro](https://ffw.press/wordpress/omgf-pro/).
85
 
86
  = Can I serve the fonts from my CDN? =
87
 
89
 
90
  = I have Google Fonts Processing set to Replace/Remove but the fonts from fonts.gstatic.com|fonts.googleapis.com are still loaded. What's going on? =
91
 
92
+ The free version of OMGF removes any fonts that are loaded in the conventional way: wp_enqueue_scripts(). If it doesn't work for you, you're theme or plugins using other methods to load Google Fonts, e.g. in the footer, WebFont Loader, etc. [Upgrade to OMGF Pro](https://ffw.press/wordpress/omgf-pro/) to automatically replace these fonts with a locally hosted version.
93
 
94
  = Does this plugin edit template files? =
95
 
97
 
98
  = The stylesheet isn't loaded? What's going on? =
99
 
100
+ The free version of OMGF enqueues the stylesheet into WordPress' head using wp_enqueue_scripts(). If the stylesheet isn't loaded, this probably means your theme isn't implementing wp_head() correctly. [Upgrade to OMGF Pro](https://ffw.press/wordpress/omgf-pro/) to automatically add the stylesheet into WordPress' head.
101
 
102
  = Does this plugin support Multi Site? I'm getting CORS errors! =
103
 
122
 
123
  == Changelog ==
124
 
125
+ = 4.2.5 | January 27th, 2021 =
126
+ * Improved compatibility with WordPress subdirectory installs.
127
+ * Implemented some actions/filters needed for upcoming release of OMGF Additional Fonts.
128
+ * Fixed duplicate preload ID's issue.
129
+ * Fixed some notices/warnings.
130
+ * Minor UX improvements.
131
+
132
  = 4.2.4 | December 8th, 2020 =
133
  * Cache keys are now fixed values instead of dynamically generated. This fixes the bug where preloads wouldn't load properly when combined with unloaded fonts of the same stylesheet.
134
  * **IMPORTANT**: To fix any bugs with preloads/unloads, emptying the cache directory is required.
templates/admin/block-welcome.phtml CHANGED
@@ -10,7 +10,7 @@
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
 
@@ -23,33 +23,33 @@ $tweetUrl = 'https://twitter.com/intent/tweet?text=I+just+optimized+my
23
  <div class="welcome-panel-content">
24
  <div class="welcome-panel-column-container">
25
  <div class="welcome-panel-column" style="width: 100%;">
26
- <?php if (apply_filters('apply_omgf_pro_promo', true)): ?>
27
- <h2>
28
- <?php _e('Support OMGF by Spreading the Word!', $plugin_text_domain); ?>
29
- </h2>
30
- <p>
31
- <?= __('Just because this plugin\'s free, doesn\'t mean there\'s nothing you can do to support me! :)', $plugin_text_domain); ?>
32
- </p>
33
- <p>
34
- <?= sprintf(__('Please help me spread the word by leaving a %s5-star review%s on Wordpress.org or sending a %sTweet%s about OMGF.', $plugin_text_domain), '<a target="_blank" href="https://wordpress.org/support/plugin/host-webfonts-local/reviews/?rate=5#new-post">', '</a>', "<a href='$tweetUrl'>", '</a>'); ?>
35
- </p>
36
- <p>
37
- <a target="_blank" class="button button-secondary button-hero" href="https://wordpress.org/support/plugin/host-webfonts-local/reviews/?rate=5#new-post"><span class="dashicons-before dashicons-star-filled"> <?php _e('Review', $plugin_text_domain); ?></span></a>
38
- <a target="_blank" class="button button-secondary button-hero" href="<?= $tweetUrl; ?>"><span class="dashicons-before dashicons-twitter"> <?php _e('Tweet', $plugin_text_domain); ?></span></a>
39
- </p>
40
- <?php else: ?>
41
- <h2>
42
- <?= __('Do you <span class="dashicons dashicons-heart ffwp-heart"></span> OMGF Pro?', $plugin_text_domain) ;?>
43
- </h2>
44
- <p>
45
- <?= __('Click the button below and receive a personal discount code for 10% off your next purchase!'); ?>
46
- </p>
47
- <p>
48
- <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>
49
- <span><?= __('(login required)', $plugin_text_domain); ?></span>
50
- </p>
51
  <?php endif; ?>
52
- <hr/>
53
  <h3>
54
  <?= __('Did you upgrade from OMGF v3 to v4?', $plugin_text_domain); ?>
55
  </h3>
@@ -62,21 +62,21 @@ $tweetUrl = 'https://twitter.com/intent/tweet?text=I+just+optimized+my
62
  <p>
63
  <?= sprintf(__('However, if you find anything that broke after the upgrade. Please send me a <a target="_blank" href="%s">support ticket</a>.', $plugin_text_domain), 'https://wordpress.org/support/plugin/host-webfonts-local/#new-post'); ?>
64
  </p>
65
- <hr/>
66
  <h3>
67
  <?php _e('Need Help?', $plugin_text_domain); ?>
68
  </h3>
69
  <ul>
70
- <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>
71
- <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>
72
  <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>
73
  <li><a target="_blank" href="<?= apply_filters('omgf_settings_sidebar_get_support_link', 'https://wordpress.org/support/plugin/host-webfonts-local/#new-post'); ?>"><?= __('Get Support', $plugin_text_domain); ?></a></li>
74
  </ul>
75
  <hr />
76
  <h4 class="signature"><?= sprintf(__('Coded with %s in The Netherlands.', $plugin_text_domain), '<span class="dashicons dashicons-heart ffwp-heart"></span>'); ?></h4>
77
  <p class="signature">
78
- <a target="_blank" title="<?= __('Visit FFWP.dev', $plugin_text_domain); ?>" href="https://ffwp.dev/wordpress-plugins/"><img class="signature-image" alt="<?= __('Visit FFWP.dev', $plugin_text_domain); ?>" src="https://ffwp.dev/wp-content/uploads/2020/09/logo-color-full@05x.png" /></a>
79
  </p>
80
  </div>
81
  </div>
82
- </div>
10
  *
11
  * @package : OMGF
12
  * @author : Daan van den Bergh
13
+ * @copyright: (c) 2021 Daan van den Bergh
14
  * @url : https://daan.dev
15
  * * * * * * * * * * * * * * * * * * * */
16
 
23
  <div class="welcome-panel-content">
24
  <div class="welcome-panel-column-container">
25
  <div class="welcome-panel-column" style="width: 100%;">
26
+ <?php if (apply_filters('apply_omgf_pro_promo', true)) : ?>
27
+ <h2>
28
+ <?php _e('Support OMGF by Spreading the Word!', $plugin_text_domain); ?>
29
+ </h2>
30
+ <p>
31
+ <?= __('Just because this plugin\'s free, doesn\'t mean there\'s nothing you can do to support me! :)', $plugin_text_domain); ?>
32
+ </p>
33
+ <p>
34
+ <?= sprintf(__('Please help me spread the word by leaving a %s5-star review%s on Wordpress.org or sending a %sTweet%s about OMGF.', $plugin_text_domain), '<a target="_blank" href="https://wordpress.org/support/plugin/host-webfonts-local/reviews/?rate=5#new-post">', '</a>', "<a href='$tweetUrl'>", '</a>'); ?>
35
+ </p>
36
+ <p>
37
+ <a target="_blank" class="button button-secondary button-hero" href="https://wordpress.org/support/plugin/host-webfonts-local/reviews/?rate=5#new-post"><span class="dashicons-before dashicons-star-filled"> <?php _e('Review', $plugin_text_domain); ?></span></a>
38
+ <a target="_blank" class="button button-secondary button-hero" href="<?= $tweetUrl; ?>"><span class="dashicons-before dashicons-twitter"> <?php _e('Tweet', $plugin_text_domain); ?></span></a>
39
+ </p>
40
+ <?php else : ?>
41
+ <h2>
42
+ <?= __('Do you <span class="dashicons dashicons-heart ffwp-heart"></span> OMGF Pro?', $plugin_text_domain); ?>
43
+ </h2>
44
+ <p>
45
+ <?= __('Click the button below and receive a personal discount code for 10% off your next purchase!'); ?>
46
+ </p>
47
+ <p>
48
+ <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>
49
+ <span><?= __('(login required)', $plugin_text_domain); ?></span>
50
+ </p>
51
  <?php endif; ?>
52
+ <hr />
53
  <h3>
54
  <?= __('Did you upgrade from OMGF v3 to v4?', $plugin_text_domain); ?>
55
  </h3>
62
  <p>
63
  <?= sprintf(__('However, if you find anything that broke after the upgrade. Please send me a <a target="_blank" href="%s">support ticket</a>.', $plugin_text_domain), 'https://wordpress.org/support/plugin/host-webfonts-local/#new-post'); ?>
64
  </p>
65
+ <hr />
66
  <h3>
67
  <?php _e('Need Help?', $plugin_text_domain); ?>
68
  </h3>
69
  <ul>
70
+ <li><a target="_blank" href="<?= apply_filters('omgf_settings_sidebar_quick_start', 'https://ffw.press/docs/omgf-pro/quick-start/'); ?>"><?= __('Quick Start Guide', $plugin_text_domain); ?></a></li>
71
+ <li><a target="_blank" href="<?= apply_filters('omgf_settings_sidebar_user_manual', 'https://ffw.press/docs/omgf-pro/user-manual/'); ?>"><?= __('User Manual', $plugin_text_domain); ?></a></li>
72
  <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>
73
  <li><a target="_blank" href="<?= apply_filters('omgf_settings_sidebar_get_support_link', 'https://wordpress.org/support/plugin/host-webfonts-local/#new-post'); ?>"><?= __('Get Support', $plugin_text_domain); ?></a></li>
74
  </ul>
75
  <hr />
76
  <h4 class="signature"><?= sprintf(__('Coded with %s in The Netherlands.', $plugin_text_domain), '<span class="dashicons dashicons-heart ffwp-heart"></span>'); ?></h4>
77
  <p class="signature">
78
+ <a target="_blank" title="<?= __('Visit FFW Press', $plugin_text_domain); ?>" href="https://ffw.press/wordpress-plugins/"><img class="signature-image" alt="<?= __('Visit FFW Press', $plugin_text_domain); ?>" src="https://ffw.press/wp-content/uploads/2021/01/logo-color-full@05x.png" /></a>
79
  </p>
80
  </div>
81
  </div>
82
+ </div>