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

Version Description

| August 2nd, 2021 = * Enhancement: Added post update notice to inform user of the plugin's database changes. The current notice you were viewed was simply, because the current DB version wasn't logged yet on your system. So if you're reading this: Ha! Made you look! ;) * Pro Feature: Added promo material for Fallback Font Stack (Pro) feature. * Enhancement: moved Stylesheet Generator to its own backend API. * Enhancement: moved Font Downloader to its own backend API. * Enhancement: Updated description of Optimization Modes. * Fix: Fixed glitch in footer news ticker. * Enhancement: Added several filter and action hooks to allow a more seamless integration with OMGF Pro and OMGF Additional Fonts. * Several code and performance optimizations.

Download this release

Release Info

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

Code changes from version 4.5.0 to 4.5.1

assets/css/omgf-admin.css CHANGED
@@ -99,7 +99,7 @@
99
  visibility: visible;
100
  }
101
  .omgf-optimize-fonts-container .omgf-optimize-fonts-manage table thead th {
102
- width: 100px;
103
  }
104
  .omgf-optimize-fonts-container .omgf-optimize-fonts-manage table tbody {
105
  border: 1px solid #ccd0d4;
@@ -110,7 +110,7 @@
110
  }
111
  .omgf-optimize-fonts-container .omgf-optimize-fonts-manage table tbody td {
112
  padding-bottom: 5px;
113
- width: 100px;
114
  }
115
  .omgf-optimize-fonts-container .omgf-optimize-fonts-manage table tbody td .unload-mass-action {
116
  font-size: 0.9em;
99
  visibility: visible;
100
  }
101
  .omgf-optimize-fonts-container .omgf-optimize-fonts-manage table thead th {
102
+ width: 13%;
103
  }
104
  .omgf-optimize-fonts-container .omgf-optimize-fonts-manage table tbody {
105
  border: 1px solid #ccd0d4;
110
  }
111
  .omgf-optimize-fonts-container .omgf-optimize-fonts-manage table tbody td {
112
  padding-bottom: 5px;
113
+ width: 13%;
114
  }
115
  .omgf-optimize-fonts-container .omgf-optimize-fonts-manage table tbody td .unload-mass-action {
116
  font-size: 0.9em;
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;;AAIJ;EACE,kBAAA;EACA,kBAAA;EACA,iBAAA;EACA,yBAAA;EACA,iBAAA;EACA,kBAAA;;AANF,8BAQE;EACE,kBAAA;EACA,YAAA;EACA,MAAA;EACA,gBAAA;EACA,eAAA;EACA,cAAA;;AAdJ,8BAiBE;EACE,gBAAA;EACA,aAAA;;AAnBJ,8BAsBE;EACE,gBAAA;;AAvBJ,8BAsBE,4BAGE;EACE,WAAA;EACA,yBAAA;;AA3BN,8BAsBE,4BAGE,MAIE;EACE,kBAAA;EACA,eAAA;EACA,iBAAA;;AAhCR,8BAsBE,4BAGE,MAIE,SAKE;EACE,kBAAA;EACA,kBAAA;EACA,SAAA;EACA,UAAA;EACA,cAAA;EACA,qCAAA;EACA,gDAA8C,oDAA+C,4BAA7F;EACA,gBAAA;EACA,WAAA;EACA,gBAAA;EACA,YAAA;EACA,aAAA;EACA,mBAAA;EACA,kBAAA;;AAhDV,8BAsBE,4BAGE,MAIE,SAKE,cAgBE;EACE,gBAAA;;AAIJ,8BAjCN,4BAGE,MAIE,SA0BG,MAAO;EACN,mBAAA;;AAxDV,8BAsBE,4BAGE,MAmCE,MACE;EACE,YAAA;;AA9DV,8BAsBE,4BAGE,MAyCE;EACE,yBAAA;;AAnER,8BAsBE,4BAGE,MAyCE,MAGE;EACE,qBAAA;EACA,UAAA;;AAvEV,8BAsBE,4BAGE,MAyCE,MAQE;EACE,mBAAA;EACA,YAAA;;AA5EV,8BAsBE,4BAGE,MAyCE,MAQE,GAIE;EACE,gBAAA;;AA/EZ,8BAsBE,4BAGE,MAyCE,MAQE,GAQE;EACE,iBAAA;EACA,gBAAA;;AAKF,8BAnER,4BAGE,MAyCE,MAsBE,GACG,WACC;EACE,oBAAA;;AA3Fd,8BAmGE,iCACE;EACE,kBAAA;;AArGN,8BAmGE,iCAKE;AAxGJ,8BAmGE,iCAME;EACE,gBAAA;EACA,UAAA;EACA,qBAAA;EACA,mBAAA;;AA7GN,8BAmGE,iCAKE,0BAOE,KAAI;AA/GV,8BAmGE,iCAME,0BAME,KAAI;EACF,oBAAA;;AAhHR,8BAmGE,iCAiBE;EACE,eAAA;EACA,iBAAA;;AAtHN,8BAmGE,iCAsBE;EACE,eAAA;EACA,eAAA;EACA,iBAAA;;AA5HN,8BAgIE;EACE,mBAAA;;AAjIJ,8BAoIE;AApIF,8BAqIE;EACE,mBAAA;;AAIJ,wBAA0C;EACxC;IACE,cAAA;;EADF,8BAGE;IACE,kBAAA;IACA,aAAA;IACA,YAAA;;;;;;AAQN;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;;;;;AAOH,gBACC;EACE,uBAAA;;AAIA,gBADF,WACG;EACC,sBAAA;;AAGF,gBALF,WAKG,WAAW;EACV,cAAA;;AAXL,gBAeC;EACE,WAAA"}
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;;AAIJ;EACE,kBAAA;EACA,kBAAA;EACA,iBAAA;EACA,yBAAA;EACA,iBAAA;EACA,kBAAA;;AANF,8BAQE;EACE,kBAAA;EACA,YAAA;EACA,MAAA;EACA,gBAAA;EACA,eAAA;EACA,cAAA;;AAdJ,8BAiBE;EACE,gBAAA;EACA,aAAA;;AAnBJ,8BAsBE;EACE,gBAAA;;AAvBJ,8BAsBE,4BAGE;EACE,WAAA;EACA,yBAAA;;AA3BN,8BAsBE,4BAGE,MAIE;EACE,kBAAA;EACA,eAAA;EACA,iBAAA;;AAhCR,8BAsBE,4BAGE,MAIE,SAKE;EACE,kBAAA;EACA,kBAAA;EACA,SAAA;EACA,UAAA;EACA,cAAA;EACA,qCAAA;EACA,gDAA8C,oDAA+C,4BAA7F;EACA,gBAAA;EACA,WAAA;EACA,gBAAA;EACA,YAAA;EACA,aAAA;EACA,mBAAA;EACA,kBAAA;;AAhDV,8BAsBE,4BAGE,MAIE,SAKE,cAgBE;EACE,gBAAA;;AAIJ,8BAjCN,4BAGE,MAIE,SA0BG,MAAO;EACN,mBAAA;;AAxDV,8BAsBE,4BAGE,MAmCE,MACE;EACE,UAAA;;AA9DV,8BAsBE,4BAGE,MAyCE;EACE,yBAAA;;AAnER,8BAsBE,4BAGE,MAyCE,MAGE;EACE,qBAAA;EACA,UAAA;;AAvEV,8BAsBE,4BAGE,MAyCE,MAQE;EACE,mBAAA;EACA,UAAA;;AA5EV,8BAsBE,4BAGE,MAyCE,MAQE,GAIE;EACE,gBAAA;;AA/EZ,8BAsBE,4BAGE,MAyCE,MAQE,GAQE;EACE,iBAAA;EACA,gBAAA;;AAKF,8BAnER,4BAGE,MAyCE,MAsBE,GACG,WACC;EACE,oBAAA;;AA3Fd,8BAmGE,iCACE;EACE,kBAAA;;AArGN,8BAmGE,iCAKE;AAxGJ,8BAmGE,iCAME;EACE,gBAAA;EACA,UAAA;EACA,qBAAA;EACA,mBAAA;;AA7GN,8BAmGE,iCAKE,0BAOE,KAAI;AA/GV,8BAmGE,iCAME,0BAME,KAAI;EACF,oBAAA;;AAhHR,8BAmGE,iCAiBE;EACE,eAAA;EACA,iBAAA;;AAtHN,8BAmGE,iCAsBE;EACE,eAAA;EACA,eAAA;EACA,iBAAA;;AA5HN,8BAgIE;EACE,mBAAA;;AAjIJ,8BAoIE;AApIF,8BAqIE;EACE,mBAAA;;AAIJ,wBAA0C;EACxC;IACE,cAAA;;EADF,8BAGE;IACE,kBAAA;IACA,aAAA;IACA,YAAA;;;;;;AAQN;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;;;;;AAOH,gBACC;EACE,uBAAA;;AAIA,gBADF,WACG;EACC,sBAAA;;AAGF,gBALF,WAKG,WAAW;EACV,cAAA;;AAXL,gBAeC;EACE,WAAA"}
assets/css/omgf-admin.less CHANGED
@@ -114,7 +114,7 @@
114
 
115
  thead {
116
  th {
117
- width: 100px;
118
  }
119
  }
120
 
@@ -128,7 +128,7 @@
128
 
129
  td {
130
  padding-bottom: 5px;
131
- width: 100px;
132
 
133
  .unload-mass-action {
134
  font-size: .9em;
114
 
115
  thead {
116
  th {
117
+ width: 13%;
118
  }
119
  }
120
 
128
 
129
  td {
130
  padding-bottom: 5px;
131
+ width: 13%;
132
 
133
  .unload-mass-action {
134
  font-size: .9em;
assets/images/ffw-press-logo.png DELETED
Binary file
assets/js/omgf-admin.js CHANGED
@@ -20,6 +20,7 @@ jQuery(document).ready(function ($) {
20
  empty_cache_directory_xhr: false,
21
  optimize_xhr: false,
22
  cache_prefix: '-ul-',
 
23
 
24
  /**
25
  * Initialize all on click events.
@@ -28,7 +29,7 @@ jQuery(document).ready(function ($) {
28
  // Settings
29
  $('input[name="omgf_optimization_mode"]').on('click', this.toggle_optimization_mode_content);
30
  $('.omgf-optimize-fonts-manage .unload').on('change', this.unload_stylesheets);
31
- $('.omgf-optimize-fonts-manage .unload').on('change', this.generate_cache_key);
32
  $('.omgf-optimize-fonts-manage .unload').on('change', this.toggle_preload);
33
  $('.omgf-optimize-fonts-manage .preload').on('change', this.toggle_unload);
34
  $('.omgf-optimize-fonts-manage .unload-italics').on('click', this.unload_italics);
@@ -49,9 +50,9 @@ jQuery(document).ready(function ($) {
49
  loop_ticker_items: function () {
50
  omgf_admin.ticker_items.forEach(function (item, index) {
51
  if (index == omgf_admin.ticker_index) {
52
- $(item).delay(110).fadeIn(500);
53
  } else {
54
- $(item).fadeOut(100);
55
  }
56
  });
57
 
@@ -122,7 +123,7 @@ jQuery(document).ready(function ($) {
122
  /**
123
  * If no or all boxes are checked, (re-)set cache key to default (without random string).
124
  */
125
- if (checked === 0 || checked === total) {
126
  cache_keys[cache_key_index] = current_handle;
127
 
128
  no_cache_key = true;
@@ -256,7 +257,8 @@ jQuery(document).ready(function ($) {
256
  type: 'POST',
257
  url: ajaxurl,
258
  data: {
259
- action: 'omgf_ajax_empty_dir'
 
260
  },
261
  beforeSend: function () {
262
  omgf_admin.show_loader();
20
  empty_cache_directory_xhr: false,
21
  optimize_xhr: false,
22
  cache_prefix: '-ul-',
23
+ cache_section: $('.omgf-empty').data('cache-section'),
24
 
25
  /**
26
  * Initialize all on click events.
29
  // Settings
30
  $('input[name="omgf_optimization_mode"]').on('click', this.toggle_optimization_mode_content);
31
  $('.omgf-optimize-fonts-manage .unload').on('change', this.unload_stylesheets);
32
+ $('.omgf-optimize-fonts-manage .unload, .omgf-optimize-fonts-manage .fallback-font-stack select').on('change', this.generate_cache_key);
33
  $('.omgf-optimize-fonts-manage .unload').on('change', this.toggle_preload);
34
  $('.omgf-optimize-fonts-manage .preload').on('change', this.toggle_unload);
35
  $('.omgf-optimize-fonts-manage .unload-italics').on('click', this.unload_italics);
50
  loop_ticker_items: function () {
51
  omgf_admin.ticker_items.forEach(function (item, index) {
52
  if (index == omgf_admin.ticker_index) {
53
+ $(item).fadeIn(500);
54
  } else {
55
+ $(item).hide(0);
56
  }
57
  });
58
 
123
  /**
124
  * If no or all boxes are checked, (re-)set cache key to default (without random string).
125
  */
126
+ if (this.nodeName !== 'SELECT' && (checked === 0 || checked === total)) {
127
  cache_keys[cache_key_index] = current_handle;
128
 
129
  no_cache_key = true;
257
  type: 'POST',
258
  url: ajaxurl,
259
  data: {
260
+ action: 'omgf_ajax_empty_dir',
261
+ section: omgf_admin.cache_section
262
  },
263
  beforeSend: function () {
264
  omgf_admin.show_loader();
host-webfonts-local.php CHANGED
@@ -4,7 +4,7 @@
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.5.0
8
  * Author: Daan from FFW.Press
9
  * Author URI: https://ffw.press
10
  * License: GPL2v2 or later
@@ -19,7 +19,8 @@ defined('ABSPATH') || exit;
19
  define('OMGF_PLUGIN_DIR', plugin_dir_path(__FILE__));
20
  define('OMGF_PLUGIN_FILE', __FILE__);
21
  define('OMGF_PLUGIN_BASENAME', plugin_basename(OMGF_PLUGIN_FILE));
22
- define('OMGF_STATIC_VERSION', '4.5.0');
 
23
 
24
  /**
25
  * Takes care of loading classes on demand.
@@ -63,4 +64,4 @@ function omgf_init()
63
  return $omgf;
64
  }
65
 
66
- add_action('plugins_loaded', 'omgf_init', 50);
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.5.1
8
  * Author: Daan from FFW.Press
9
  * Author URI: https://ffw.press
10
  * License: GPL2v2 or later
19
  define('OMGF_PLUGIN_DIR', plugin_dir_path(__FILE__));
20
  define('OMGF_PLUGIN_FILE', __FILE__);
21
  define('OMGF_PLUGIN_BASENAME', plugin_basename(OMGF_PLUGIN_FILE));
22
+ define('OMGF_STATIC_VERSION', '4.5.1');
23
+ define('OMGF_DB_VERSION', '4.5.1');
24
 
25
  /**
26
  * Takes care of loading classes on demand.
64
  return $omgf;
65
  }
66
 
67
+ omgf_init();
includes/admin/class-settings.php CHANGED
@@ -18,8 +18,13 @@ defined('ABSPATH') || exit;
18
 
19
  class OMGF_Admin_Settings extends OMGF_Admin
20
  {
21
- const OMGF_ADMIN_PAGE = 'optimize-webfonts';
22
- const OMGF_NEWS_REEL = 'omgf_news_reel';
 
 
 
 
 
23
 
24
  /**
25
  * Settings Fields
@@ -84,6 +89,39 @@ class OMGF_Admin_Settings extends OMGF_Admin
84
  'tibetan' => 'Tibetan',
85
  'vietnamese' => 'Vietnamese'
86
  ];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87
  const OMGF_AMP_HANDLING_OPTIONS = [
88
  'fallback' => 'Fallback (default)',
89
  'disable' => 'Disable'
@@ -119,6 +157,7 @@ class OMGF_Admin_Settings extends OMGF_Admin
119
  * Miscellaneous
120
  */
121
  const OMGF_OPTIONS_GENERAL_PAGE_OPTIMIZE_WEBFONTS = 'options-general.php?page=optimize-webfonts';
 
122
  const FFWP_WORDPRESS_PLUGINS_OMGF_PRO = 'https://ffw.press/wordpress/omgf-pro/';
123
 
124
  /** @var string $active_tab */
@@ -383,7 +422,7 @@ class OMGF_Admin_Settings extends OMGF_Admin
383
  ?>
384
  <?php if ($this->active_tab !== self::OMGF_SETTINGS_FIELD_HELP) : ?>
385
  <?php submit_button($this->submit_button_text, 'primary', 'submit', false); ?>
386
- <a id="omgf-empty" class="omgf-empty button-cancel"><?php _e('Empty Cache Directory', $this->plugin_text_domain); ?></a>
387
  <?php endif; ?>
388
  </form>
389
  <?php
18
 
19
  class OMGF_Admin_Settings extends OMGF_Admin
20
  {
21
+ const OMGF_ADMIN_PAGE = 'optimize-webfonts';
22
+
23
+ /**
24
+ * Transients
25
+ */
26
+ const OMGF_NEWS_REEL = 'omgf_news_reel';
27
+ const OMGF_CURRENT_DB_VERSION = 'omgf_current_db_version';
28
 
29
  /**
30
  * Settings Fields
89
  'tibetan' => 'Tibetan',
90
  'vietnamese' => 'Vietnamese'
91
  ];
92
+ const OMGF_FALLBACK_FONT_STACKS_OPTIONS = [
93
+ 'arial' => 'Arial',
94
+ 'baskerville' => 'Baskerville',
95
+ 'bodoni-mt' => 'Bodoni MT',
96
+ 'calibri' => 'Calibri',
97
+ 'calisto-mt' => 'Calisto MT',
98
+ 'cambria' => 'Cambria',
99
+ 'candara' => 'Candara',
100
+ 'century-gothic' => 'Century Gothic',
101
+ 'consolas' => 'Consolas',
102
+ 'copperplate' => 'Copperplate Gothic',
103
+ 'courier-new' => 'Courier New',
104
+ 'dejavu-sans' => 'Dejavu Sans',
105
+ 'didot' => 'Didot',
106
+ 'franklin-gothic' => 'Franklin Gothic',
107
+ 'garamond' => 'Garamond',
108
+ 'georgia' => 'Georgia',
109
+ 'gill-sans' => 'Gill Sans',
110
+ 'goudy-old-style' => 'Goudy Old Style',
111
+ 'helvetica' => 'Helvetica',
112
+ 'impact' => 'Impact',
113
+ 'lucida-bright' => 'Lucida Bright',
114
+ 'lucida-sans' => 'Lucida Sans',
115
+ 'ms-sans-serif' => 'Microsoft Sans Serif',
116
+ 'optima' => 'Optima',
117
+ 'palatino' => 'Palatino',
118
+ 'perpetua' => 'Perpetua',
119
+ 'rockwell' => 'Rockwell',
120
+ 'segoe-ui' => 'Segoe UI',
121
+ 'tahoma' => 'Tahoma',
122
+ 'trebuchet-ms' => 'Trebuchet MS',
123
+ 'verdana' => 'Verdana'
124
+ ];
125
  const OMGF_AMP_HANDLING_OPTIONS = [
126
  'fallback' => 'Fallback (default)',
127
  'disable' => 'Disable'
157
  * Miscellaneous
158
  */
159
  const OMGF_OPTIONS_GENERAL_PAGE_OPTIMIZE_WEBFONTS = 'options-general.php?page=optimize-webfonts';
160
+ const OMGF_PLUGINS_INSTALL_CHANGELOG_SECTION = 'plugin-install.php?tab=plugin-information&plugin=host-webfonts-local&TB_iframe=true&width=772&height=1015&section=changelog';
161
  const FFWP_WORDPRESS_PLUGINS_OMGF_PRO = 'https://ffw.press/wordpress/omgf-pro/';
162
 
163
  /** @var string $active_tab */
422
  ?>
423
  <?php if ($this->active_tab !== self::OMGF_SETTINGS_FIELD_HELP) : ?>
424
  <?php submit_button($this->submit_button_text, 'primary', 'submit', false); ?>
425
+ <a id="omgf-empty" data-cache-section="/*" class="omgf-empty button-cancel"><?php _e('Empty Cache Directory', $this->plugin_text_domain); ?></a>
426
  <?php endif; ?>
427
  </form>
428
  <?php
includes/admin/settings/class-optimize.php CHANGED
@@ -192,6 +192,7 @@ class OMGF_Admin_Settings_Optimize extends OMGF_Admin_Settings_Builder
192
  <th><?= __('Weight', $this->plugin_text_domain); ?></th>
193
  <th><?= __('Preload', $this->plugin_text_domain); ?><span class="dashicons dashicons-info tooltip"><span class="tooltip-text"><span class="inline-text"><?= __('Preload font files (before everything else) so they will be available as soon as they are required for the rendering of the page. Only use preload for font files that are used above the fold.', $this->plugin_text_domain); ?></span><img width="230" class="illustration" src="<?= plugin_dir_url(OMGF_PLUGIN_FILE) . 'assets/images/above-the-fold.png'; ?>" /></span></span></th>
194
  <th><?= __('Do not load', $this->plugin_text_domain); ?></th>
 
195
  </tr>
196
  </thead>
197
  <?php
@@ -205,7 +206,7 @@ class OMGF_Admin_Settings_Optimize extends OMGF_Admin_Settings_Builder
205
  ?>
206
  <tbody class="stylesheet" id="<?= $handle; ?>">
207
  <tr>
208
- <th colspan="5"><?= sprintf(__('Stylesheet handle: %s', $this->plugin_text_domain), $handle); ?></th>
209
  </tr>
210
  <?php foreach ($fonts as $font) : ?>
211
  <?php if (!is_object($font) || count((array) $font->variants) <= 0) continue; ?>
@@ -213,7 +214,17 @@ class OMGF_Admin_Settings_Optimize extends OMGF_Admin_Settings_Builder
213
  $aka = in_array($font->id, OMGF_API_Download::OMGF_RENAMED_GOOGLE_FONTS) ? array_search($font->id, OMGF_API_Download::OMGF_RENAMED_GOOGLE_FONTS) : '';
214
  ?>
215
  <tr class="font-family" data-id="<?= $font->id; ?>">
216
- <td colspan="5"><span class="family"><em><?= $font->family; ?><?= $aka ? ' (' . sprintf(__('formerly known as <strong>%s</strong>', $this->plugin_text_domain) . ')', ucfirst($aka)) : ''; ?></em></span> <span class="unload-mass-action">(<a href="#" class="unload-italics"><?= __('Unload italics', $this->plugin_text_domain); ?></a> <span class="dashicons dashicons-info tooltip"><span class="tooltip-text"><?= __('In most situations you can safely unload all Italic font styles. Modern browsers are capable of mimicking Italic font styles.', $this->plugin_text_domain); ?></span></span> | <a href="#" class="unload-all"><?= __('Unload all', $this->plugin_text_domain); ?></a> | <a href="#" class="load-all"><?= __('Load all', $this->plugin_text_domain); ?></a>)</span></td>
 
 
 
 
 
 
 
 
 
 
217
  </tr>
218
  <?php foreach ($font->variants as $variant) : ?>
219
  <tr>
@@ -241,7 +252,7 @@ class OMGF_Admin_Settings_Optimize extends OMGF_Admin_Settings_Builder
241
  <p>
242
  <span class="dashicons-before dashicons-info-outline"></span>
243
  <?php if (OMGF_OPTIMIZATION_MODE == 'manual') : ?>
244
- <em><?= sprintf(__("This list is populated with all Google Fonts captured and downloaded 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>
245
  <?php else : ?>
246
  <?php
247
  $no_cache_param = '?omgf_optimize=' . substr(md5(microtime()), rand(0, 26), 5);
192
  <th><?= __('Weight', $this->plugin_text_domain); ?></th>
193
  <th><?= __('Preload', $this->plugin_text_domain); ?><span class="dashicons dashicons-info tooltip"><span class="tooltip-text"><span class="inline-text"><?= __('Preload font files (before everything else) so they will be available as soon as they are required for the rendering of the page. Only use preload for font files that are used above the fold.', $this->plugin_text_domain); ?></span><img width="230" class="illustration" src="<?= plugin_dir_url(OMGF_PLUGIN_FILE) . 'assets/images/above-the-fold.png'; ?>" /></span></span></th>
194
  <th><?= __('Do not load', $this->plugin_text_domain); ?></th>
195
+ <th><?= __('Fallback Font Stack (Pro)', $this->plugin_text_domain); ?></th>
196
  </tr>
197
  </thead>
198
  <?php
206
  ?>
207
  <tbody class="stylesheet" id="<?= $handle; ?>">
208
  <tr>
209
+ <th colspan="6"><?= sprintf(__('Stylesheet handle: %s', $this->plugin_text_domain), $handle); ?></th>
210
  </tr>
211
  <?php foreach ($fonts as $font) : ?>
212
  <?php if (!is_object($font) || count((array) $font->variants) <= 0) continue; ?>
214
  $aka = in_array($font->id, OMGF_API_Download::OMGF_RENAMED_GOOGLE_FONTS) ? array_search($font->id, OMGF_API_Download::OMGF_RENAMED_GOOGLE_FONTS) : '';
215
  ?>
216
  <tr class="font-family" data-id="<?= $font->id; ?>">
217
+ <td colspan="5">
218
+ <span class="family"><em><?= $font->family; ?><?= $aka ? ' (' . sprintf(__('formerly known as <strong>%s</strong>', $this->plugin_text_domain) . ')', ucfirst($aka)) : ''; ?></em></span> <span class="unload-mass-action">(<a href="#" class="unload-italics"><?= __('Unload italics', $this->plugin_text_domain); ?></a> <span class="dashicons dashicons-info tooltip"><span class="tooltip-text"><?= __('In most situations you can safely unload all Italic font styles. Modern browsers are capable of mimicking Italic font styles.', $this->plugin_text_domain); ?></span></span> | <a href="#" class="unload-all"><?= __('Unload all', $this->plugin_text_domain); ?></a> | <a href="#" class="load-all"><?= __('Load all', $this->plugin_text_domain); ?></a>)</span>
219
+ </td>
220
+ <td class="fallback-font-stack">
221
+ <select data-handle="<?= $handle; ?>" <?= apply_filters('omgf_pro_fallback_font_stack_setting_disabled', true) ? 'disabled' : ''; ?> name="omgf_pro_fallback_font_stack[<?= $handle; ?>][<?= $font->id; ?>]">
222
+ <option value=''><?= __('None (default)', $this->plugin_text_domain); ?></option>
223
+ <?php foreach (OMGF_Admin_Settings::OMGF_FALLBACK_FONT_STACKS_OPTIONS as $value => $label) : ?>
224
+ <option <?= defined('OMGF_PRO_FALLBACK_FONT_STACK') && isset(OMGF_PRO_FALLBACK_FONT_STACK[$handle][$font->id]) && OMGF_PRO_FALLBACK_FONT_STACK[$handle][$font->id] == $value ? 'selected' : ''; ?> value="<?= $value; ?>"><?= $label; ?></option>
225
+ <?php endforeach; ?>
226
+ </select>
227
+ </td>
228
  </tr>
229
  <?php foreach ($font->variants as $variant) : ?>
230
  <tr>
252
  <p>
253
  <span class="dashicons-before dashicons-info-outline"></span>
254
  <?php if (OMGF_OPTIMIZATION_MODE == 'manual') : ?>
255
+ <em><?= sprintf(__("This list is populated with all Google Fonts captured and downloaded 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, switch to <strong>Automatic (Pro)</strong> and visit the pages containing the stylesheets you'd like to optimize. This list will automatically be populated with the captured fonts.", $this->plugin_text_domain), OMGF_MANUAL_OPTIMIZE_URL); ?></em>
256
  <?php else : ?>
257
  <?php
258
  $no_cache_param = '?omgf_optimize=' . substr(md5(microtime()), rand(0, 26), 5);
includes/api/class-download.php CHANGED
@@ -153,13 +153,13 @@ class OMGF_API_Download extends WP_REST_Controller
153
 
154
  foreach ($file_types as $file_type) {
155
  if (isset($variant->$file_type)) {
156
- $variant->$file_type = $this->download($variant->$file_type, $filename, $file_type);
157
  }
158
  }
159
  }
160
  }
161
 
162
- $stylesheet = $this->generate_stylesheet($fonts);
163
  $local_file = $this->path . '/' . $this->handle . '.css';
164
 
165
  file_put_contents($local_file, $stylesheet);
@@ -415,7 +415,7 @@ class OMGF_API_Download extends WP_REST_Controller
415
  * If $variants is empty and this is the first run, i.e. there are no unloaded fonts (yet)
416
  * return all available variants.
417
  */
418
- if (empty($variants) && !isset(omgf::unloaded_fonts()[$stylesheet_handle][$font_id])) {
419
  return $available;
420
  }
421
 
@@ -437,107 +437,6 @@ class OMGF_API_Download extends WP_REST_Controller
437
  );
438
  }
439
 
440
- /**
441
- * @param mixed $url
442
- * @param mixed $filename
443
- * @param mixed $extension
444
- * @return string
445
- * @throws SodiumException
446
- * @throws TypeError
447
- */
448
- private function download($url, $filename, $extension)
449
- {
450
- if (!function_exists('download_url')) {
451
- require_once ABSPATH . 'wp-admin/includes/file.php';
452
- }
453
-
454
- wp_mkdir_p($this->path);
455
-
456
- $file = $this->path . '/' . $filename . '.' . $extension;
457
- $file_uri = str_replace(WP_CONTENT_DIR, '', $file);
458
-
459
- if (file_exists($file)) {
460
- return content_url($file_uri);
461
- }
462
-
463
- if (strpos($url, '//') == 0) {
464
- $url = 'https:' . $url;
465
- }
466
-
467
- $tmp = download_url($url);
468
- copy($tmp, $file);
469
- @unlink($tmp);
470
-
471
- return content_url($file_uri);
472
- }
473
-
474
- /**
475
- * @param $fonts
476
- *
477
- * @return string
478
- */
479
- private function generate_stylesheet($fonts)
480
- {
481
- /**
482
- * Which file types should we download and include in the stylesheet?
483
- *
484
- * @since v4.5
485
- */
486
- $file_types = apply_filters('omgf_include_file_types', ['woff2', 'woff', 'eot', 'ttf']);
487
- $font_display = OMGF_DISPLAY_OPTION;
488
- $stylesheet = "/**\n * Auto Generated by OMGF\n * @author: Daan van den Bergh\n * @url: https://ffw.press\n */\n\n";
489
-
490
- foreach ($fonts as $font) {
491
- /**
492
- * If Font Family's name was recently renamed, the old name should be used so no manual changes have to be made
493
- * to the stylesheet after processing.
494
- */
495
- $renamed_font_family = in_array($font->id, self::OMGF_RENAMED_GOOGLE_FONTS)
496
- ? array_search($font->id, self::OMGF_RENAMED_GOOGLE_FONTS)
497
- : '';
498
-
499
- foreach ($font->variants as $variant) {
500
- $font_family = $renamed_font_family ? '\'' . ucfirst($renamed_font_family) . '\'' : $variant->fontFamily;
501
- $font_style = $variant->fontStyle;
502
- $font_weight = $variant->fontWeight;
503
- $stylesheet .= "@font-face {\n";
504
- $stylesheet .= " font-family: $font_family;\n";
505
- $stylesheet .= " font-style: $font_style;\n";
506
- $stylesheet .= " font-weight: $font_weight;\n";
507
- $stylesheet .= " font-display: $font_display;\n";
508
-
509
- /**
510
- * For IE compatibility, EOT is added before the local family name is defined.
511
- */
512
- if (in_array('eot', $file_types)) {
513
- $stylesheet .= " src: url('" . $variant->eot . "');\n";
514
- $eot_key = array_search('eot', $file_types);
515
- unset($file_types[$eot_key]);
516
- }
517
-
518
- $local_src = '';
519
-
520
- if (isset($variant->local) && is_array($variant->local)) {
521
- foreach ($variant->local as $local) {
522
- $local_src .= "local('$local'), ";
523
- }
524
- }
525
-
526
- $stylesheet .= " src: $local_src\n";
527
- $font_src_url = [];
528
-
529
- foreach ($file_types as $file_type) {
530
- $font_src_url = $font_src_url + (isset($variant->$file_type) ? [$file_type => $variant->$file_type] : []);
531
- }
532
-
533
- $stylesheet .= $this->build_source_string($font_src_url);
534
- $stylesheet .= "}\n";
535
- }
536
- }
537
-
538
- return $stylesheet;
539
- }
540
-
541
  /**
542
  * When unload is used, insert the cache key for the variants still in use.
543
  *
@@ -566,29 +465,4 @@ class OMGF_API_Download extends WP_REST_Controller
566
 
567
  return $stylesheets;
568
  }
569
-
570
- /**
571
- * @param $sources
572
- * @param string $type
573
- * @param bool $end_semi_colon
574
- *
575
- * @return string
576
- */
577
- private function build_source_string($sources, $type = 'url', $end_semi_colon = true)
578
- {
579
- $last_src = end($sources);
580
- $source = '';
581
-
582
- foreach ($sources as $format => $url) {
583
- $source .= " $type('$url')" . (!is_numeric($format) ? " format('$format')" : '');
584
-
585
- if ($url === $last_src && $end_semi_colon) {
586
- $source .= ";\n";
587
- } else {
588
- $source .= ",\n";
589
- }
590
- }
591
-
592
- return $source;
593
- }
594
  }
153
 
154
  foreach ($file_types as $file_type) {
155
  if (isset($variant->$file_type)) {
156
+ $variant->$file_type = OMGF::download($variant->$file_type, $filename, $file_type, $this->path);
157
  }
158
  }
159
  }
160
  }
161
 
162
+ $stylesheet = OMGF::generate_stylesheet($fonts, $original_handle);
163
  $local_file = $this->path . '/' . $this->handle . '.css';
164
 
165
  file_put_contents($local_file, $stylesheet);
415
  * If $variants is empty and this is the first run, i.e. there are no unloaded fonts (yet)
416
  * return all available variants.
417
  */
418
+ if (empty($variants) && !isset(OMGF::unloaded_fonts()[$stylesheet_handle][$font_id])) {
419
  return $available;
420
  }
421
 
437
  );
438
  }
439
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
440
  /**
441
  * When unload is used, insert the cache key for the variants still in use.
442
  *
465
 
466
  return $stylesheets;
467
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
468
  }
includes/class-admin.php CHANGED
@@ -14,6 +14,8 @@
14
  * @url : https://daan.dev
15
  * * * * * * * * * * * * * * * * * * * */
16
 
 
 
17
  defined('ABSPATH') || exit;
18
 
19
  class OMGF_Admin
@@ -51,6 +53,7 @@ class OMGF_Admin
51
  $this->do_detection_settings();
52
  $this->do_advanced_settings();
53
  $this->do_help();
 
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);
@@ -112,6 +115,27 @@ class OMGF_Admin
112
  return new OMGF_Admin_Settings_Help();
113
  }
114
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115
  /**
116
  * @param $old_value
117
  * @param $value
14
  * @url : https://daan.dev
15
  * * * * * * * * * * * * * * * * * * * */
16
 
17
+ use function PHPSTORM_META\map;
18
+
19
  defined('ABSPATH') || exit;
20
 
21
  class OMGF_Admin
53
  $this->do_detection_settings();
54
  $this->do_advanced_settings();
55
  $this->do_help();
56
+ $this->maybe_do_after_update_notice();
57
 
58
  add_filter('pre_update_option_omgf_optimized_fonts', [$this, 'decode_option'], 10, 3);
59
  add_filter('pre_update_option_omgf_cache_keys', [$this, 'clean_up_cache'], 10, 3);
115
  return new OMGF_Admin_Settings_Help();
116
  }
117
 
118
+ /**
119
+ * Checks if an update notice should be displayed after updating.
120
+ */
121
+ private function maybe_do_after_update_notice()
122
+ {
123
+ if (version_compare(OMGF_CURRENT_DB_VERSION, OMGF_DB_VERSION, '<')) {
124
+ OMGF_Admin_Notice::set_notice(
125
+ sprintf(
126
+ __('Thank you for updating OMGF to v%s! This version contains database changes. <a href="%s">Verify your settings</a> and make sure everything is as you left it or, <a href="%s">view the changelog</a> for details. ', $this->plugin_text_domain),
127
+ OMGF_DB_VERSION,
128
+ admin_url(OMGF_Admin_Settings::OMGF_OPTIONS_GENERAL_PAGE_OPTIMIZE_WEBFONTS),
129
+ admin_url(OMGF_Admin_Settings::OMGF_PLUGINS_INSTALL_CHANGELOG_SECTION)
130
+ ),
131
+ 'omgf-post-update',
132
+ false
133
+ );
134
+
135
+ update_option(OMGF_Admin_Settings::OMGF_CURRENT_DB_VERSION, OMGF_DB_VERSION);
136
+ }
137
+ }
138
+
139
  /**
140
  * @param $old_value
141
  * @param $value
includes/class-ajax.php CHANGED
@@ -35,19 +35,35 @@ class OMGF_AJAX
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) {
35
  public function empty_directory()
36
  {
37
  try {
38
+ $section = $_POST['section'];
39
+ $entries = array_filter((array) glob(OMGF_FONTS_DIR . $section));
40
+
41
+ $instructions = apply_filters(
42
+ 'omgf_clean_up_instructions',
43
+ [
44
+ 'section' => $section,
45
+ 'exclude' => [],
46
+ 'queue' => [
47
+ OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_OPTIMIZED_FONTS,
48
+ OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_UNLOAD_FONTS,
49
+ OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_PRELOAD_FONTS,
50
+ OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_UNLOAD_STYLESHEETS
51
+ ]
52
+ ]
53
+ );
54
 
55
  foreach ($entries as $entry) {
56
+ if (in_array($entry, $instructions['exclude'])) {
57
+ continue;
58
+ }
59
+
60
  OMGF::delete($entry);
61
  }
62
 
63
+
64
+ foreach ($instructions['queue'] as $option) {
65
+ delete_option($option);
66
+ }
 
 
 
67
 
68
  OMGF_Admin_Notice::set_notice(__('Cache directory successfully emptied.', $this->plugin_text_domain));
69
  } catch (\Exception $e) {
includes/class-download.php ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ defined('ABSPATH') || exit;
3
+
4
+ /* * * * * * * * * * * * * * * * * * * * *
5
+ *
6
+ * ██████╗ ███╗ ███╗ ██████╗ ███████╗
7
+ * ██╔═══██╗████╗ ████║██╔════╝ ██╔════╝
8
+ * ██║ ██║██╔████╔██║██║ ███╗█████╗
9
+ * ██║ ██║██║╚██╔╝██║██║ ██║██╔══╝
10
+ * ╚██████╔╝██║ ╚═╝ ██║╚██████╔╝██║
11
+ * ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝
12
+ *
13
+ * @package : OMGF
14
+ * @author : Daan van den Bergh
15
+ * @copyright: (c) 2021 Daan van den Bergh
16
+ * @url : https://daan.dev
17
+ * * * * * * * * * * * * * * * * * * * */
18
+
19
+ class OMGF_Download
20
+ {
21
+ private $url;
22
+
23
+ private $filename;
24
+
25
+ private $extension;
26
+
27
+ private $path;
28
+
29
+ /**
30
+ * OMGF_Download constructor.
31
+ */
32
+ public function __construct(
33
+ string $url,
34
+ string $filename,
35
+ string $extension,
36
+ string $path
37
+ ) {
38
+ $this->url = $url;
39
+ $this->filename = $filename;
40
+ $this->extension = $extension;
41
+ $this->path = $path;
42
+ }
43
+
44
+ /**
45
+ * Download $url to $path and return content_url() to $filename.
46
+ *
47
+ * @return string
48
+ *
49
+ * @throws SodiumException
50
+ * @throws TypeError
51
+ */
52
+ public function download()
53
+ {
54
+ if (!function_exists('download_url')) {
55
+ require_once ABSPATH . 'wp-admin/includes/file.php';
56
+ }
57
+
58
+ wp_mkdir_p($this->path);
59
+
60
+ $file = $this->path . '/' . $this->filename . '.' . $this->extension;
61
+ $file_uri = str_replace(WP_CONTENT_DIR, '', $file);
62
+
63
+ if (file_exists($file)) {
64
+ return content_url($file_uri);
65
+ }
66
+
67
+ $tmp = download_url($this->url);
68
+ copy($tmp, $file);
69
+ @unlink($tmp);
70
+
71
+ return content_url($file_uri);
72
+ }
73
+ }
includes/class-omgf.php CHANGED
@@ -26,12 +26,11 @@ class OMGF
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('admin_init', [$this, 'do_optimize']);
@@ -50,6 +49,7 @@ class OMGF
50
  public function define_constants()
51
  {
52
  define('OMGF_SITE_URL', 'https://daan.dev');
 
53
  define('OMGF_OPTIMIZATION_MODE', esc_attr(get_option(OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_OPTIMIZATION_MODE, 'manual')));
54
  define('OMGF_MANUAL_OPTIMIZE_URL', esc_attr(get_option(OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_MANUAL_OPTIMIZE_URL, site_url())));
55
  define('OMGF_FONT_PROCESSING', esc_attr(get_option(OMGF_Admin_Settings::OMGF_DETECTION_SETTING_FONT_PROCESSING, 'replace')));
@@ -62,6 +62,27 @@ class OMGF
62
  define('OMGF_CACHE_KEYS', esc_attr(get_option(OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_CACHE_KEYS, '')));
63
  }
64
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
  /**
66
  * @return array
67
  */
@@ -150,6 +171,35 @@ class OMGF
150
  return '';
151
  }
152
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
153
  /**
154
  * @return OMGF_Admin_Settings
155
  */
26
  $this->define_constants();
27
 
28
  if (is_admin()) {
29
+ add_action('plugins_loaded', [$this, 'init_admin'], 50);
 
30
  }
31
 
32
  if (!is_admin()) {
33
+ add_action('plugins_loaded', [$this, 'init_frontend'], 50);
34
  }
35
 
36
  add_action('admin_init', [$this, 'do_optimize']);
49
  public function define_constants()
50
  {
51
  define('OMGF_SITE_URL', 'https://daan.dev');
52
+ define('OMGF_CURRENT_DB_VERSION', esc_attr(get_option(OMGF_Admin_Settings::OMGF_CURRENT_DB_VERSION)));
53
  define('OMGF_OPTIMIZATION_MODE', esc_attr(get_option(OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_OPTIMIZATION_MODE, 'manual')));
54
  define('OMGF_MANUAL_OPTIMIZE_URL', esc_attr(get_option(OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_MANUAL_OPTIMIZE_URL, site_url())));
55
  define('OMGF_FONT_PROCESSING', esc_attr(get_option(OMGF_Admin_Settings::OMGF_DETECTION_SETTING_FONT_PROCESSING, 'replace')));
62
  define('OMGF_CACHE_KEYS', esc_attr(get_option(OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_CACHE_KEYS, '')));
63
  }
64
 
65
+ /**
66
+ * Required in Admin.
67
+ *
68
+ * @return void
69
+ */
70
+ public function init_admin()
71
+ {
72
+ $this->do_settings();
73
+ $this->add_ajax_hooks();
74
+ }
75
+
76
+ /**
77
+ * Required in Frontend.
78
+ *
79
+ * @return void
80
+ */
81
+ public function init_frontend()
82
+ {
83
+ $this->do_frontend();
84
+ }
85
+
86
  /**
87
  * @return array
88
  */
171
  return '';
172
  }
173
 
174
+ /**
175
+ * Download $url and save as $filename.$extension to $path.
176
+ *
177
+ * @param mixed $url
178
+ * @param mixed $filename
179
+ * @param mixed $extension
180
+ * @param mixed $path
181
+ *
182
+ * @return string
183
+ */
184
+ public static function download($url, $filename, $extension, $path)
185
+ {
186
+ $download = new OMGF_Download($url, $filename, $extension, $path);
187
+
188
+ return $download->download();
189
+ }
190
+
191
+ /**
192
+ * @param mixed $fonts
193
+ *
194
+ * @return string
195
+ */
196
+ public static function generate_stylesheet($fonts, $handle = '', $plugin = 'OMGF')
197
+ {
198
+ $generator = new OMGF_StylesheetGenerator($fonts, $handle, $plugin);
199
+
200
+ return $generator->generate();
201
+ }
202
+
203
  /**
204
  * @return OMGF_Admin_Settings
205
  */
includes/class-stylesheet-generator.php ADDED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ defined('ABSPATH') || exit;
3
+
4
+ /* * * * * * * * * * * * * * * * * * * * *
5
+ *
6
+ * ██████╗ ███╗ ███╗ ██████╗ ███████╗
7
+ * ██╔═══██╗████╗ ████║██╔════╝ ██╔════╝
8
+ * ██║ ██║██╔████╔██║██║ ███╗█████╗
9
+ * ██║ ██║██║╚██╔╝██║██║ ██║██╔══╝
10
+ * ╚██████╔╝██║ ╚═╝ ██║╚██████╔╝██║
11
+ * ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝
12
+ *
13
+ * @package : OMGF
14
+ * @author : Daan van den Bergh
15
+ * @copyright: (c) 2021 Daan van den Bergh
16
+ * @url : https://daan.dev
17
+ * * * * * * * * * * * * * * * * * * * */
18
+
19
+ class OMGF_StylesheetGenerator
20
+ {
21
+ /** @var $fonts */
22
+ private $fonts;
23
+
24
+ /** @var string $handle */
25
+ private $handle;
26
+
27
+ /** @var string $plugin */
28
+ private $plugin;
29
+
30
+ /**
31
+ * OMGF_GenerateStylesheet constructor.
32
+ */
33
+ public function __construct(
34
+ $fonts,
35
+ string $handle,
36
+ string $plugin
37
+ ) {
38
+ $this->fonts = $fonts;
39
+ $this->handle = $handle;
40
+ $this->plugin = $plugin;
41
+ }
42
+
43
+ /**
44
+ * Generate a stylesheet based on the provided $fonts.
45
+ *
46
+ * @return string
47
+ */
48
+ public function generate()
49
+ {
50
+ /**
51
+ * Which file types should we download and include in the stylesheet?
52
+ *
53
+ * @since v4.5
54
+ */
55
+ $file_types = apply_filters('omgf_include_file_types', ['woff2', 'woff', 'eot', 'ttf', 'svg']);
56
+ $font_display = OMGF_DISPLAY_OPTION;
57
+ $stylesheet = "/**\n * Auto Generated by $this->plugin\n * @author: Daan van den Bergh\n * @url: https://ffw.press\n */\n\n";
58
+
59
+ foreach ($this->fonts as $font) {
60
+ /**
61
+ * If Font Family's name was recently renamed, the old name should be used so no manual changes have to be made
62
+ * to the stylesheet after processing.
63
+ */
64
+ $renamed_font_family = in_array($font->id, OMGF_API_Download::OMGF_RENAMED_GOOGLE_FONTS)
65
+ ? array_search($font->id, OMGF_API_Download::OMGF_RENAMED_GOOGLE_FONTS)
66
+ : '';
67
+
68
+ foreach ($font->variants as $variant) {
69
+ /**
70
+ * Filter font_family name.
71
+ *
72
+ * @since v4.5.1
73
+ */
74
+ $font_family = apply_filters('omgf_generate_stylesheet_font_family', $renamed_font_family ? ucfirst($renamed_font_family) : $variant->fontFamily);
75
+ $font_style = $variant->fontStyle;
76
+ $font_weight = $variant->fontWeight;
77
+ $stylesheet .= "@font-face {\n";
78
+ $stylesheet .= " font-family: $font_family;\n";
79
+ $stylesheet .= " font-style: $font_style;\n";
80
+ $stylesheet .= " font-weight: $font_weight;\n";
81
+ $stylesheet .= " font-display: $font_display;\n";
82
+
83
+ /**
84
+ * For IE compatibility, EOT is added before the local family name is defined.
85
+ */
86
+ if (in_array('eot', $file_types)) {
87
+ $stylesheet .= " src: url('" . $variant->eot . "');\n";
88
+ $eot_key = array_search('eot', $file_types);
89
+ unset($file_types[$eot_key]);
90
+ }
91
+
92
+ $local_src = '';
93
+
94
+ if (isset($variant->local) && is_array($variant->local)) {
95
+ foreach ($variant->local as $local) {
96
+ $local_src .= "local('$local'), ";
97
+ }
98
+ }
99
+
100
+ $stylesheet .= " src: $local_src\n";
101
+ $font_src_url = [];
102
+
103
+ foreach ($file_types as $file_type) {
104
+ $font_src_url = $font_src_url + (isset($variant->$file_type) ? [$file_type => $variant->$file_type] : []);
105
+ }
106
+
107
+ $stylesheet .= $this->build_source_string($font_src_url);
108
+ $stylesheet .= "}\n";
109
+ }
110
+ }
111
+
112
+ return $stylesheet;
113
+ }
114
+
115
+ /**
116
+ * @param $sources
117
+ * @param string $type
118
+ * @param bool $end_semi_colon
119
+ *
120
+ * @return string
121
+ */
122
+ private function build_source_string($sources, $type = 'url', $end_semi_colon = true)
123
+ {
124
+ $last_src = end($sources);
125
+ $source = '';
126
+
127
+ foreach ($sources as $format => $url) {
128
+ $source .= " $type('$url')" . (!is_numeric($format) ? " format('$format')" : '');
129
+
130
+ if ($url === $last_src && $end_semi_colon) {
131
+ $source .= ";\n";
132
+ } else {
133
+ $source .= ",\n";
134
+ }
135
+ }
136
+
137
+ return $source;
138
+ }
139
+ }
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: DaanvandenBergh
3
  Tags: google, fonts, gdpr, cache, speed, preload, font-display, webfonts, subsets, remove, minimize, external, requests
4
  Requires at least: 4.6
5
  Tested up to: 5.8
6
- Stable tag: 4.5.0
7
  Requires PHP: 7.0
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
@@ -15,19 +15,19 @@ OMGF automagically caches the Google Fonts used by your theme/plugins locally. N
15
  > How could using fonts via Google's service possibly run afoul of GDPR? The fact of the matter is that, when a font is requested by the user's browser, their IP is logged by Google and used for analytics.
16
  > — Lifehacker
17
 
18
- Leverage Browser Cache, Minimize DNS requests and serve your Google Fonts in a 100% GDPR compliant way with OMGF!
19
 
20
  OMGF is written with performance and user-friendliness in mind. It uses the Google Fonts Helper API to automatically cache the fonts your theme and plugins use to **minimize DNS requests** and speed up your WordPress website.
21
 
22
  = How Does It Work? =
23
 
24
- After installing the plugin, choose your Optimization Mode: Manual (default) or Automatic.
25
 
26
- When *Manual* is selected, you can simply configure OMGF to work in the way you want, and run its detection mechanism on an address of your choosing.
27
 
28
- In *Automatic* Mode, OMGF runs silently in the background and captures any requests made to fonts.googleapis.com or fonts.gstatic.com. When a webpage is first loaded, it reroutes these requests to its own Download API and copies the fonts over to your server. Then it generates a stylesheet for your fonts including EOT, TTF, WOFF and WOFF2 formats to guarantee maximum cross browser compatibility!
29
 
30
- When the fonts are downloaded and the stylesheet is generated, it rewrites every URL (pointing to fonts.googleapis.com or fonts.gstatic.com) to the locally hosted variant.
31
 
32
  Please keep in mind that, although I try to make the configuration of this plugin as easy as possible, the concept of locally hosting a file or optimizing Google Fonts for *Pagespeed Insights* or *GT Metrix* has proven to be confusing for some people. If you're not sure of what your doing, please consult a SEO expert or Webdeveloper to help you with the configuration of this plugin or [hire me to do it for you](https://ffw.press/wordpress/omgf-expert-configuration/).
33
 
@@ -43,10 +43,11 @@ Please keep in mind that, although I try to make the configuration of this plugi
43
 
44
  Everything in the free version, plus:
45
 
 
46
  - Automatically remove/replace all Google Fonts throughout the entire document/page,
47
  - Also supports WebFont Loader (webfont.js), Early Access Google Fonts and requests in stylesheets using @import (@font-face coming soon...).
48
  - Automatically generate different stylesheets for pages with another configuration of Google Fonts.
49
- - Combine all Google Fonts (made by your theme and/or plugins) stylesheets into one file,
50
  - Deduplicate Google Fonts stylesheets,
51
  - Define file types to include in stylesheet (WOFF, WOFF2, EOT, TTF, SVG),
52
  - Reduce loading time and page size, by forcing the used subset(s) for all Google Fonts requests,
@@ -62,30 +63,31 @@ Everything in the free version, plus:
62
  == Installation ==
63
 
64
  1. Upload the plugin files to the `/wp-content/plugins/host-webfonts-local` directory, or install the plugin through the WordPress plugins screen directly.
65
- 1. Activate the plugin through the 'Plugins' screen in WordPress
66
- 1. Use the Settings -> Optimize Google Fonts screen to configure the plugin
67
 
68
- For a more comprehensive guide for configuration, click [here](https://daan.dev/wordpress/host-google-fonts-locally/).
69
 
70
  == Frequently Asked Questions ==
71
 
72
  = Why do my fonts load slow the first time? =
73
 
74
- That's because OMGF's download API is capturing the request and immediately downloading all the fonts. After the fonts are downloaded and the stylesheet is generated, the stylesheet will load just as fast as any other file request.
75
 
76
  = I don't know what I'm doing! Can you help? =
77
 
78
- Of course :) But first calm down and read this [comprehensive guide on how to configure OMGF](https://daan.dev/wordpress/host-google-fonts-locally/). If you have any questions afterwards, visit the [Support Forum](https://wordpress.org/support/plugin/host-webfonts-local).
79
 
80
  = I have another file I want to host locally. Could you make a plugin? =
81
 
82
- Maintaining three plugins besides my daily 9-to-5 job is a handful, so no. If you're looking for a way to host analytics.js locally; please install [CAOS](https://wordpress.org/plugins/host-analyticsjs-local/). For anything else, please follow the steps in [this how-to](https://daan.dev/how-to/host-js-locally-crontab/).
83
 
84
  = How come my font isn't available in OMGF? =
85
 
86
  This could be for several reasons:
87
  1. Have you checked if your font is available on Google Fonts?
88
- 1. Is your font listed as an open source font, or is it a premium font? For obvious reasons, OMGF only has access to open source fonts.
 
89
 
90
  = Does this plugin remove resource hints, e.g. preconnect, preload or dns-prefetch? =
91
 
@@ -93,7 +95,7 @@ No, to automatically remove resource hints pointing to fonts.googleapis.com or f
93
 
94
  = Can I serve the fonts from my CDN? =
95
 
96
- Yes, you can. Enter the url of your CDN and empty OMGF's cache directory.
97
 
98
  = 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? =
99
 
@@ -124,12 +126,22 @@ No, not yet. But I will definitely try to make it compatible in the future!
124
  == Screenshots ==
125
 
126
  1. OMGF's Optimize Fonts screen. These settings affect the downloaded files and generated stylesheet(s).
127
- 2. After you've saved your changes, the Manage Optimized Google Fonts overview will show a list of detected fonts and will allow you to tweak it as you wish.
128
  3. Tweak how OMGF's detection mechanism will work and how it'll treat detected fonts.
129
  4. Advanced Settings. Change these to make OMGF work with your configuration (if needed). The default settings will suffice for most configurations.
130
 
131
  == Changelog ==
132
 
 
 
 
 
 
 
 
 
 
 
133
  = 4.5.0 | July 28th, 2021 =
134
  * [Removed] WOFF2 only option is superseded by Include File Types option, only available in OMGF Pro.
135
  * [Removed] CDN URL, Cache URI and Relative URL options are combined into Fonts Source URL option, only available in OMGF Pro.
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.8
6
+ Stable tag: 4.5.1
7
  Requires PHP: 7.0
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
15
  > How could using fonts via Google's service possibly run afoul of GDPR? The fact of the matter is that, when a font is requested by the user's browser, their IP is logged by Google and used for analytics.
16
  > — Lifehacker
17
 
18
+ Leverage Browser Cache, Minimize DNS requests, reduce Cumulative Layout Shift and serve your Google Fonts in a 100% GDPR compliant way with OMGF!
19
 
20
  OMGF is written with performance and user-friendliness in mind. It uses the Google Fonts Helper API to automatically cache the fonts your theme and plugins use to **minimize DNS requests** and speed up your WordPress website.
21
 
22
  = How Does It Work? =
23
 
24
+ After installing the plugin, choose your Optimization Mode: Manual (default) or Automatic (only available in Pro).
25
 
26
+ When *Manual* is selected, you can simply configure OMGF to work in the way you want, and run its detection mechanism on an address of your choosing. Tweak the stylesheet(s) as you wish and these will be used throughout your site.
27
 
28
+ In *Automatic* (Pro) Mode, OMGF runs silently in the background and captures any requests made to fonts.googleapis.com or fonts.gstatic.com. When a webpage is first loaded, it reroutes these requests to its own Download API and copies the fonts over to your server. Then it generates a stylesheet for your fonts including SVG, EOT, TTF, WOFF and WOFF2 formats to guarantee maximum cross browser compatibility!
29
 
30
+ When the fonts are downloaded and the stylesheet is generated, it rewrites every URL (pointing to fonts.googleapis.com or fonts.gstatic.com) to the locally hosted stylesheet and/or font.
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
 
43
 
44
  Everything in the free version, plus:
45
 
46
+ - Specify a Fallback Font Stack for every Google Font, to reduce Cumulative Layout Shift,
47
  - Automatically remove/replace all Google Fonts throughout the entire document/page,
48
  - Also supports WebFont Loader (webfont.js), Early Access Google Fonts and requests in stylesheets using @import (@font-face coming soon...).
49
  - Automatically generate different stylesheets for pages with another configuration of Google Fonts.
50
+ - Combine all Google Fonts stylesheets (requested by your theme and/or plugins) into one file,
51
  - Deduplicate Google Fonts stylesheets,
52
  - Define file types to include in stylesheet (WOFF, WOFF2, EOT, TTF, SVG),
53
  - Reduce loading time and page size, by forcing the used subset(s) for all Google Fonts requests,
63
  == Installation ==
64
 
65
  1. Upload the plugin files to the `/wp-content/plugins/host-webfonts-local` directory, or install the plugin through the WordPress plugins screen directly.
66
+ 2. Activate the plugin through the 'Plugins' screen in WordPress
67
+ 3. Use the Settings -> Optimize Google Fonts screen to configure the plugin
68
 
69
+ For a more comprehensive guide on configuring OMGF, check out the [user manual](https://ffw.press/docs/omgf-pro/user-manual/)
70
 
71
  == Frequently Asked Questions ==
72
 
73
  = Why do my fonts load slow the first time? =
74
 
75
+ When OMGF runs in Automatic (Pro) mode, all requests to Google Fonts' API are rewritten and point to OMGF's on-premise download API. The API downloads the fonts and generates the stylesheet, which takes a while. When this is finished, the API will not be used anymore and the stylesheet and its fonts will be loaded directly, just like any other file.
76
 
77
  = I don't know what I'm doing! Can you help? =
78
 
79
+ Of course :) But first calm down and read the [user manual](https://ffw.press/docs/omgf-pro/user-manual/). If you have any questions afterwards, visit the [Support Forum](https://wordpress.org/support/plugin/host-webfonts-local).
80
 
81
  = I have another file I want to host locally. Could you make a plugin? =
82
 
83
+ I already have my hands full with the plugins I maintain, so no. If you're looking for a way to host analytics.js locally; please install [CAOS](https://wordpress.org/plugins/host-analyticsjs-local/). For anything else, please follow the steps in [this how-to](https://daan.dev/how-to/host-js-locally-crontab/).
84
 
85
  = How come my font isn't available in OMGF? =
86
 
87
  This could be for several reasons:
88
  1. Have you checked if your font is available on Google Fonts?
89
+ 2. Is your font listed as an open source font, or is it a premium font? For obvious reasons, OMGF only has access to open source fonts.
90
+ 3. Your font's name was changed, if so, please send in a support ticket, so we can figure out the new name and I can add support for it to OMGF.
91
 
92
  = Does this plugin remove resource hints, e.g. preconnect, preload or dns-prefetch? =
93
 
95
 
96
  = Can I serve the fonts from my CDN? =
97
 
98
+ Yes, using the Fonts Source URL (Pro) feature, you can modify the source of the stylesheet and fonts to be served from your CDN. [Upgrade to OMGF Pro](https://ffw.press/wordpress/omgf-pro/).
99
 
100
  = 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? =
101
 
126
  == Screenshots ==
127
 
128
  1. OMGF's Optimize Fonts screen. These settings affect the downloaded files and generated stylesheet(s).
129
+ 2. After you've saved your changes, the Manage Optimized Google Fonts overview will show a list of detected fonts and will allowing you to easily unload and preload fonts.
130
  3. Tweak how OMGF's detection mechanism will work and how it'll treat detected fonts.
131
  4. Advanced Settings. Change these to make OMGF work with your configuration (if needed). The default settings will suffice for most configurations.
132
 
133
  == Changelog ==
134
 
135
+ = 4.5.1 | August 2nd, 2021 =
136
+ * Enhancement: Added post update notice to inform user of the plugin's database changes. The current notice you were viewed was simply, because the current DB version wasn't logged yet on your system. So if you're reading this: Ha! Made you look! ;)
137
+ * Pro Feature: Added promo material for Fallback Font Stack (Pro) feature.
138
+ * Enhancement: moved Stylesheet Generator to its own backend API.
139
+ * Enhancement: moved Font Downloader to its own backend API.
140
+ * Enhancement: Updated description of Optimization Modes.
141
+ * Fix: Fixed glitch in footer news ticker.
142
+ * Enhancement: Added several filter and action hooks to allow a more seamless integration with OMGF Pro and OMGF Additional Fonts.
143
+ * Several code and performance optimizations.
144
+
145
  = 4.5.0 | July 28th, 2021 =
146
  * [Removed] WOFF2 only option is superseded by Include File Types option, only available in OMGF Pro.
147
  * [Removed] CDN URL, Cache URI and Relative URL options are combined into Fonts Source URL option, only available in OMGF Pro.