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

Version Description

  • Fix: Added Fallback API URL for when Google Fonts Helper is down.
  • Enhancement: Added extra error handling in Manual Optimization Mode.
  • Fix: API requests made in Manual Optimization Mode are no longer forced to SSL. It now uses the protocol configured in Settings > General > WordPress URL.
  • Fix: Stylesheet handles containing spaces would prevent Optimize Google Fonts screen from rendering properly.
  • Several refactors and code optimizations.
Download this release

Release Info

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

Code changes from version 4.5.5 to 4.5.6

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.5
8
  * Author: Daan from FFW.Press
9
  * Author URI: https://ffw.press
10
  * License: GPL2v2 or later
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.6
8
  * Author: Daan from FFW.Press
9
  * Author URI: https://ffw.press
10
  * License: GPL2v2 or later
includes/admin/settings/class-builder.php CHANGED
@@ -158,10 +158,10 @@ class OMGF_Admin_Settings_Builder
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; ?>" />
158
  * @param $value
159
  * @param $description
160
  */
161
+ public function do_number($label, $name, $value, $description, $min = 0, $visible = true)
162
  {
163
  ?>
164
+ <tr valign="top" <?= $visible ? '' : 'style="display: none;"'; ?>>
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; ?>" />
includes/admin/settings/class-detection.php CHANGED
@@ -68,7 +68,7 @@ class OMGF_Admin_Settings_Detection extends OMGF_Admin_Settings_Builder
68
  $disabled = apply_filters($name . '_setting_disabled', true) ? 'disabled' : '';
69
  ?>
70
  <label for="<?= $name; ?>">
71
- <input type="checkbox" name="<?= $name; ?>" <?= $checked ? 'checked="checked"' : ''; ?> <?= $disabled; ?> /><?= $data['label']; ?>
72
  &nbsp;
73
  </label>
74
  <?php endforeach; ?>
68
  $disabled = apply_filters($name . '_setting_disabled', true) ? 'disabled' : '';
69
  ?>
70
  <label for="<?= $name; ?>">
71
+ <input type="checkbox" name="<?= $name; ?>" id="<?= $name; ?>" <?= $checked ? 'checked="checked"' : ''; ?> <?= $disabled; ?> /><?= $data['label']; ?>
72
  &nbsp;
73
  </label>
74
  <?php endforeach; ?>
includes/admin/settings/class-optimize.php CHANGED
@@ -159,7 +159,7 @@ class OMGF_Admin_Settings_Optimize extends OMGF_Admin_Settings_Builder
159
  */
160
  public function do_optimize_fonts_contents()
161
  {
162
- $this->optimized_fonts = omgf_init()::optimized_fonts();
163
  ?>
164
  <span class="option-title"><?= __('Manage Optimized Fonts', $this->plugin_text_domain); ?></span>
165
  <?php if ($this->optimized_fonts) : ?>
@@ -196,11 +196,11 @@ class OMGF_Admin_Settings_Optimize extends OMGF_Admin_Settings_Builder
196
  </tr>
197
  </thead>
198
  <?php
199
- $cache_handles = omgf_init()::cache_keys();
200
  ?>
201
  <?php foreach ($this->optimized_fonts as $handle => $fonts) : ?>
202
  <?php
203
- if (!omgf_init()::get_cache_key($handle)) {
204
  $cache_handles[] = $handle;
205
  }
206
  ?>
@@ -215,7 +215,7 @@ class OMGF_Admin_Settings_Optimize extends OMGF_Admin_Settings_Builder
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; ?>]">
@@ -254,14 +254,12 @@ class OMGF_Admin_Settings_Optimize extends OMGF_Admin_Settings_Builder
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);
259
- ?>
260
  <em><?= sprintf(__("This list is automatically populated with Google Fonts captured 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>
261
  <?php endif; ?>
262
  </p>
263
  </div>
264
- <input type="hidden" name="<?= OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_OPTIMIZED_FONTS; ?>" value="<?= serialize($this->optimized_fonts); ?>" />
265
  <input type="hidden" name="<?= OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_MANUAL_OPTIMIZE_URL; ?>" value="<?= OMGF_MANUAL_OPTIMIZE_URL; ?>" />
266
  <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; ?>" />
267
  <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); ?>" />
159
  */
160
  public function do_optimize_fonts_contents()
161
  {
162
+ $this->optimized_fonts = OMGF::optimized_fonts();
163
  ?>
164
  <span class="option-title"><?= __('Manage Optimized Fonts', $this->plugin_text_domain); ?></span>
165
  <?php if ($this->optimized_fonts) : ?>
196
  </tr>
197
  </thead>
198
  <?php
199
+ $cache_handles = OMGF::cache_keys();
200
  ?>
201
  <?php foreach ($this->optimized_fonts as $handle => $fonts) : ?>
202
  <?php
203
+ if (!OMGF::get_cache_key($handle)) {
204
  $cache_handles[] = $handle;
205
  }
206
  ?>
215
  ?>
216
  <tr class="font-family" data-id="<?= $font->id; ?>">
217
  <td colspan="5">
218
+ <span class="family"><em><?= rawurldecode($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; ?>]">
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 $no_cache_param = '?omgf_optimize=' . substr(md5(microtime()), rand(0, 26), 5); ?>
 
 
258
  <em><?= sprintf(__("This list is automatically populated with Google Fonts captured 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>
259
  <?php endif; ?>
260
  </p>
261
  </div>
262
+ <input type="hidden" name="<?= OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_OPTIMIZED_FONTS; ?>" value='<?= serialize($this->optimized_fonts); ?>' />
263
  <input type="hidden" name="<?= OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_MANUAL_OPTIMIZE_URL; ?>" value="<?= OMGF_MANUAL_OPTIMIZE_URL; ?>" />
264
  <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; ?>" />
265
  <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); ?>" />
includes/api/class-download.php CHANGED
@@ -18,7 +18,9 @@ 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
  /**
24
  * If a font changed names recently, this array will map the old name (key) to the new name (value).
@@ -133,7 +135,7 @@ class OMGF_API_Download extends WP_REST_Controller
133
 
134
  $requested_variants = $this->parse_requested_variants($requested_variants, $font);
135
 
136
- if ($unloaded_fonts = omgf_init()::unloaded_fonts()) {
137
  $font_id = $font->id;
138
 
139
  // Now we're sure we got 'em all. We can safely dequeue those we don't want.
@@ -156,9 +158,23 @@ class OMGF_API_Download extends WP_REST_Controller
156
  foreach ($fonts as &$font) {
157
  $font_id = $font->id;
158
 
 
 
 
 
 
 
 
159
  foreach ($font->variants as &$variant) {
160
  $filename = strtolower($font_id . '-' . $variant->fontStyle . '-' . $variant->fontWeight);
161
 
 
 
 
 
 
 
 
162
  foreach ($file_types as $file_type) {
163
  if (isset($variant->$file_type)) {
164
  $variant->$file_type = OMGF::download($variant->$file_type, $filename, $file_type, $this->path);
@@ -283,7 +299,7 @@ class OMGF_API_Download extends WP_REST_Controller
283
  */
284
  private function grab_font_family($font_family, $query)
285
  {
286
- $url = self::OMGF_GOOGLE_FONTS_API_URL . '/api/fonts/%s';
287
 
288
  list($family) = explode(':', $font_family);
289
  $family = strtolower(str_replace([' ', '+'], '-', $family));
@@ -314,7 +330,7 @@ class OMGF_API_Download extends WP_REST_Controller
314
  }
315
 
316
  $response = wp_remote_get(
317
- sprintf($url, $family) . $query_string
318
  );
319
 
320
  if (is_wp_error($response)) {
@@ -323,25 +339,27 @@ class OMGF_API_Download extends WP_REST_Controller
323
 
324
  $response_code = wp_remote_retrieve_response_code($response);
325
 
326
- if ($response_code !== 200) {
327
  $font_family = str_replace('-', ' ', $family);
328
- $error_message = wp_remote_retrieve_body($response);
 
329
  $message = sprintf(__('<strong>%s</strong> could not be found. The API returned the following error: %s.', $this->plugin_text_domain), ucwords($font_family), $error_message);
330
 
331
- OMGF_Admin_Notice::set_notice(
332
- $message,
333
- 'omgf_api_error',
334
- false,
335
- 'error'
336
- );
337
 
338
- if ($error_message == 'Not found') {
 
 
 
339
  $message = sprintf(__('Please verify that %s is available for free at Google Fonts by doing <a href="%s" target="_blank">a manual search</a>. Maybe it\'s a Premium font?', $this->plugin_text_domain), ucwords($font_family), 'https://fonts.google.com/?query=' . str_replace('-', '+', $family));
340
 
341
  OMGF_Admin_Notice::set_notice($message, 'omgf_api_info_not_found', false, 'info');
342
  }
343
 
344
- if ($error_message == 'Internal Server Error') {
345
  $message = sprintf(__('Try using the Force Subsets option (available in OMGF Pro) to force loading %s in a subset in which it\'s actually available. Use the Language filter <a href="%s" target="_blank">here</a> to verify which subsets are available for %s.', $this->plugin_text_domain), ucwords($font_family), 'https://fonts.google.com/?query=' . str_replace('-', '+', $family), ucwords($font_family));
346
 
347
  OMGF_Admin_Notice::set_notice($message, 'omgf_api_info_internal_server_error', false, 'info');
@@ -353,6 +371,40 @@ class OMGF_API_Download extends WP_REST_Controller
353
  return json_decode(wp_remote_retrieve_body($response));
354
  }
355
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
356
  /**
357
  * @param $font_families
358
  * @param $font
18
 
19
  class OMGF_API_Download extends WP_REST_Controller
20
  {
21
+ const OMGF_GOOGLE_FONTS_API_URL = 'https://google-webfonts-helper.herokuapp.com/api/fonts/';
22
+ const OMGF_GOOGLE_FONTS_API_FALLBACK = 'https://n8n-google-fonts-helper.herokuapp.com/api/fonts/';
23
+ const OMGF_USE_FALLBACK_API_TRANSIENT = 'omgf_use_fallback_api';
24
 
25
  /**
26
  * If a font changed names recently, this array will map the old name (key) to the new name (value).
135
 
136
  $requested_variants = $this->parse_requested_variants($requested_variants, $font);
137
 
138
+ if ($unloaded_fonts = OMGF::unloaded_fonts()) {
139
  $font_id = $font->id;
140
 
141
  // Now we're sure we got 'em all. We can safely dequeue those we don't want.
158
  foreach ($fonts as &$font) {
159
  $font_id = $font->id;
160
 
161
+ /**
162
+ * Sanitize font family, because it may contain spaces.
163
+ *
164
+ * @since v4.5.6
165
+ */
166
+ $font->family = rawurlencode($font->family);
167
+
168
  foreach ($font->variants as &$variant) {
169
  $filename = strtolower($font_id . '-' . $variant->fontStyle . '-' . $variant->fontWeight);
170
 
171
+ /**
172
+ * Encode font family, because it may contain spaces.
173
+ *
174
+ * @since v4.5.6
175
+ */
176
+ $variant->fontFamily = rawurlencode($variant->fontFamily);
177
+
178
  foreach ($file_types as $file_type) {
179
  if (isset($variant->$file_type)) {
180
  $variant->$file_type = OMGF::download($variant->$file_type, $filename, $file_type, $this->path);
299
  */
300
  private function grab_font_family($font_family, $query)
301
  {
302
+ $url = $this->get_working_service_url();
303
 
304
  list($family) = explode(':', $font_family);
305
  $family = strtolower(str_replace([' ', '+'], '-', $family));
330
  }
331
 
332
  $response = wp_remote_get(
333
+ sprintf($url . '%s', $family) . $query_string
334
  );
335
 
336
  if (is_wp_error($response)) {
339
 
340
  $response_code = wp_remote_retrieve_response_code($response);
341
 
342
+ if ($response_code != 200) {
343
  $font_family = str_replace('-', ' ', $family);
344
+ $error_body = wp_remote_retrieve_body($response);
345
+ $error_message = wp_remote_retrieve_response_message($response);
346
  $message = sprintf(__('<strong>%s</strong> could not be found. The API returned the following error: %s.', $this->plugin_text_domain), ucwords($font_family), $error_message);
347
 
348
+ OMGF_Admin_Notice::set_notice($message, 'omgf_api_error', false, 'error');
349
+
350
+ if ($error_message == 'Service Unavailable') {
351
+ $message = __('Google Fonts Helper API is currently unavailable. Try again later.', $this->plugin_text_domain);
 
 
352
 
353
+ OMGF_Admin_Notice::set_notice($message, 'omgf_api_error', true, 'error', $response_code);
354
+ }
355
+
356
+ if ($error_body == 'Not found') {
357
  $message = sprintf(__('Please verify that %s is available for free at Google Fonts by doing <a href="%s" target="_blank">a manual search</a>. Maybe it\'s a Premium font?', $this->plugin_text_domain), ucwords($font_family), 'https://fonts.google.com/?query=' . str_replace('-', '+', $family));
358
 
359
  OMGF_Admin_Notice::set_notice($message, 'omgf_api_info_not_found', false, 'info');
360
  }
361
 
362
+ if ($error_body == 'Internal Server Error') {
363
  $message = sprintf(__('Try using the Force Subsets option (available in OMGF Pro) to force loading %s in a subset in which it\'s actually available. Use the Language filter <a href="%s" target="_blank">here</a> to verify which subsets are available for %s.', $this->plugin_text_domain), ucwords($font_family), 'https://fonts.google.com/?query=' . str_replace('-', '+', $family), ucwords($font_family));
364
 
365
  OMGF_Admin_Notice::set_notice($message, 'omgf_api_info_internal_server_error', false, 'info');
371
  return json_decode(wp_remote_retrieve_body($response));
372
  }
373
 
374
+ /**
375
+ * Because the regular Google Webfonts Helper API tends to go offline sometimes, this function allows us
376
+ * to use fallback services.
377
+ *
378
+ * TODO: Setup own mirror.
379
+ *
380
+ * @return string Will return regular API url if fallback API url fails, too. Error handling later on will display a
381
+ * proper message to the user.
382
+ */
383
+ private function get_working_service_url()
384
+ {
385
+ /**
386
+ * If this transient returns true, then that means that the regular API has failed in the last 24 hours.
387
+ */
388
+ if (get_transient(self::OMGF_USE_FALLBACK_API_TRANSIENT)) {
389
+ return self::OMGF_GOOGLE_FONTS_API_FALLBACK;
390
+ }
391
+
392
+ $url = self::OMGF_GOOGLE_FONTS_API_URL;
393
+ $response = wp_remote_get($url);
394
+
395
+ if (is_wp_error($response) || wp_remote_retrieve_response_code($response) != 200) {
396
+ set_transient(self::OMGF_USE_FALLBACK_API_TRANSIENT, true, DAY_IN_SECONDS);
397
+
398
+ $response = wp_remote_get(self::OMGF_GOOGLE_FONTS_API_FALLBACK);
399
+
400
+ if (!is_wp_error($response) && wp_remote_retrieve_response_code($response) == 200) {
401
+ $url = self::OMGF_GOOGLE_FONTS_API_FALLBACK;
402
+ }
403
+ }
404
+
405
+ return $url;
406
+ }
407
+
408
  /**
409
  * @param $font_families
410
  * @param $font
includes/class-admin.php CHANGED
@@ -55,7 +55,7 @@ class OMGF_Admin
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);
60
  add_filter('pre_update_option', [$this, 'settings_changed'], 10, 3);
61
  }
@@ -137,15 +137,17 @@ class OMGF_Admin
137
  }
138
 
139
  /**
 
 
 
140
  * @param $old_value
141
  * @param $value
142
- * @param $option_name
143
  *
144
- * @return mixed
145
  */
146
- public function decode_option($old_value, $value, $option_name)
147
  {
148
- return $value;
149
  }
150
 
151
  /**
@@ -203,7 +205,15 @@ class OMGF_Admin
203
  $wp_settings_errors = [];
204
  }
205
 
206
- add_settings_error('general', 'omgf_settings_changed', __('Settings changed. <a href="#" data-cache-section="/*" class="omgf-empty">Click here</a> to empty OMGF\'s cache.', $this->plugin_text_domain), 'success');
 
 
 
 
 
 
 
 
207
  }
208
 
209
  return $value;
55
  $this->do_help();
56
  $this->maybe_do_after_update_notice();
57
 
58
+ add_filter('pre_update_option_omgf_optimized_fonts', [$this, 'update_optimized_fonts'], 10, 2);
59
  add_filter('pre_update_option_omgf_cache_keys', [$this, 'clean_up_cache'], 10, 3);
60
  add_filter('pre_update_option', [$this, 'settings_changed'], 10, 3);
61
  }
137
  }
138
 
139
  /**
140
+ * This fixes a bug where the admin screen wouldn't properly be updated after omgf_optimized_fonts
141
+ * was updated by the API.
142
+ *
143
  * @param $old_value
144
  * @param $value
 
145
  *
146
+ * @return bool|array
147
  */
148
+ public function update_optimized_fonts($value, $old_value)
149
  {
150
+ return $old_value;
151
  }
152
 
153
  /**
205
  $wp_settings_errors = [];
206
  }
207
 
208
+ add_settings_error(
209
+ 'general',
210
+ 'omgf_settings_changed',
211
+ sprintf(
212
+ __('Settings changed. <a href="#" data-cache-section="/*" data-nonce="%s" class="omgf-empty">Click here</a> to empty OMGF\'s cache.', $this->plugin_text_domain),
213
+ wp_create_nonce(OMGF_Admin_Settings::OMGF_ADMIN_PAGE)
214
+ ),
215
+ 'success'
216
+ );
217
  }
218
 
219
  return $value;
includes/class-ajax.php CHANGED
@@ -33,6 +33,7 @@ class OMGF_AJAX
33
  * Empty cache directory.
34
  *
35
  * @since v4.5.3: Hardened security.
 
36
  */
37
  public function empty_directory()
38
  {
33
  * Empty cache directory.
34
  *
35
  * @since v4.5.3: Hardened security.
36
+ * @since v4.5.5: Added authentication.
37
  */
38
  public function empty_directory()
39
  {
includes/class-download.php CHANGED
@@ -68,6 +68,6 @@ class OMGF_Download
68
  copy($tmp, $file);
69
  @unlink($tmp);
70
 
71
- return content_url($file_uri);
72
  }
73
  }
68
  copy($tmp, $file);
69
  @unlink($tmp);
70
 
71
+ return urlencode(content_url($file_uri));
72
  }
73
  }
includes/class-omgf.php CHANGED
@@ -94,6 +94,15 @@ class OMGF
94
  $optimized_fonts = get_option(OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_OPTIMIZED_FONTS, []) ?: [];
95
  }
96
 
 
 
 
 
 
 
 
 
 
97
  return $optimized_fonts;
98
  }
99
 
94
  $optimized_fonts = get_option(OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_OPTIMIZED_FONTS, []) ?: [];
95
  }
96
 
97
+ /**
98
+ * get_option() should take care of this, but sometimes it doesn't.
99
+ *
100
+ * @since v4.5.6
101
+ */
102
+ if (is_string($optimized_fonts)) {
103
+ $optimized_fonts = unserialize($optimized_fonts);
104
+ }
105
+
106
  return $optimized_fonts;
107
  }
108
 
includes/class-optimize.php CHANGED
@@ -1,4 +1,6 @@
1
  <?php
 
 
2
  /* * * * * * * * * * * * * * * * * * * * *
3
  *
4
  * ██████╗ ███╗ ███╗ ██████╗ ███████╗
@@ -14,21 +16,16 @@
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 string */
25
  private $settings_page = '';
26
 
27
  /** @var string */
28
  private $settings_tab = '';
29
 
30
- /** @var string */
31
- private $settings_updated = '';
32
 
33
  /**
34
  * OMGF_Optimize constructor.
@@ -37,7 +34,7 @@ class OMGF_Optimize
37
  {
38
  $this->settings_page = $_GET['page'] ?? '';
39
  $this->settings_tab = $_GET['tab'] ?? OMGF_Admin_Settings::OMGF_SETTINGS_FIELD_OPTIMIZE;
40
- $this->settings_updated = $_GET['settings-updated'] ?? '';
41
 
42
  $this->init();
43
  }
@@ -77,7 +74,7 @@ class OMGF_Optimize
77
  * to 0 further down the road.
78
  *
79
  * @param mixed $url
80
- * @return bool
81
  */
82
  public function verify_ssl($args)
83
  {
@@ -87,107 +84,12 @@ class OMGF_Optimize
87
  }
88
 
89
  /**
90
- * @return void
 
 
91
  */
92
  private function run_manual()
93
  {
94
- $url = esc_url_raw(OMGF_MANUAL_OPTIMIZE_URL);
95
-
96
- $front_html = $this->remote_get($url);
97
-
98
- if (is_wp_error($front_html)) {
99
- $this->frontend_fetch_failed($front_html);
100
- }
101
-
102
- $urls = [];
103
- $document = new DOMDocument();
104
- libxml_use_internal_errors(true);
105
- @$document->loadHtml(wp_remote_retrieve_body($front_html));
106
-
107
- foreach ($document->getElementsByTagName('link') as $link) {
108
- /** @var $link DOMElement */
109
- if ($link->hasAttribute('href') && strpos($link->getAttribute('href'), '/omgf/v1/download/')) {
110
- $urls[] = $link->getAttribute('href');
111
- }
112
- }
113
-
114
- if (empty($urls)) {
115
- $this->no_urls_found();
116
- }
117
-
118
- foreach ($urls as $url) {
119
- $download = $this->remote_get($url);
120
-
121
- if (is_wp_error($download)) {
122
- $this->download_failed($download);
123
- }
124
- }
125
-
126
- $this->optimization_succeeded();
127
- }
128
-
129
- /**
130
- * @return void
131
- */
132
- private function optimization_succeeded()
133
- {
134
- add_settings_error('general', 'omgf_optimization_success', __('Optimization completed successfully.'), 'success');
135
-
136
- OMGF_Admin_Notice::set_notice(
137
- __('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),
138
- 'omgf-cache-notice',
139
- false,
140
- 'warning'
141
- );
142
- }
143
-
144
- /**
145
- * @param $download WP_Error
146
- */
147
- private function download_failed($download)
148
- {
149
- 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');
150
- }
151
-
152
- /**
153
- * @param $front_html WP_Error
154
- */
155
- private function frontend_fetch_failed($front_html)
156
- {
157
- 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');
158
- }
159
-
160
- /**
161
- * @return void
162
- */
163
- private function no_urls_found()
164
- {
165
- 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');
166
- }
167
-
168
- /**
169
- * Wrapper for wp_remote_get() with preset params.
170
- *
171
- * @param mixed $url
172
- * @return array|WP_Error
173
- */
174
- private function remote_get($url)
175
- {
176
- return wp_remote_get(
177
- $this->no_cache_optimize_url($url),
178
- [
179
- 'timeout' => 30
180
- ]
181
- );
182
- }
183
-
184
- /**
185
- * @param $url
186
- *
187
- * @return string
188
- */
189
- private function no_cache_optimize_url($url)
190
- {
191
- return add_query_arg(['omgf_optimize' => 1, 'nocache' => substr(md5(microtime()), rand(0, 26), 5)], $url);
192
  }
193
  }
1
  <?php
2
+ defined('ABSPATH') || exit;
3
+
4
  /* * * * * * * * * * * * * * * * * * * * *
5
  *
6
  * ██████╗ ███╗ ███╗ ██████╗ ███████╗
16
  * @url : https://daan.dev
17
  * * * * * * * * * * * * * * * * * * * */
18
 
 
 
19
  class OMGF_Optimize
20
  {
 
 
 
21
  /** @var string */
22
  private $settings_page = '';
23
 
24
  /** @var string */
25
  private $settings_tab = '';
26
 
27
+ /** @var bool */
28
+ private $settings_updated = false;
29
 
30
  /**
31
  * OMGF_Optimize constructor.
34
  {
35
  $this->settings_page = $_GET['page'] ?? '';
36
  $this->settings_tab = $_GET['tab'] ?? OMGF_Admin_Settings::OMGF_SETTINGS_FIELD_OPTIMIZE;
37
+ $this->settings_updated = isset($_GET['settings-updated']);
38
 
39
  $this->init();
40
  }
74
  * to 0 further down the road.
75
  *
76
  * @param mixed $url
77
+ * @return array
78
  */
79
  public function verify_ssl($args)
80
  {
84
  }
85
 
86
  /**
87
+ * Run Manual mode.
88
+ *
89
+ * @return void
90
  */
91
  private function run_manual()
92
  {
93
+ new OMGF_OptimizationMode_Manual();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  }
95
  }
includes/class-stylesheet-generator.php CHANGED
@@ -71,7 +71,7 @@ class OMGF_StylesheetGenerator
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";
@@ -84,7 +84,7 @@ class OMGF_StylesheetGenerator
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
  }
@@ -101,7 +101,7 @@ class OMGF_StylesheetGenerator
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);
71
  *
72
  * @since v4.5.1
73
  */
74
+ $font_family = apply_filters('omgf_generate_stylesheet_font_family', $renamed_font_family ? ucfirst(rawurldecode($renamed_font_family)) : rawurldecode($variant->fontFamily));
75
  $font_style = $variant->fontStyle;
76
  $font_weight = $variant->fontWeight;
77
  $stylesheet .= "@font-face {\n";
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('" . urldecode($variant->eot) . "');\n";
88
  $eot_key = array_search('eot', $file_types);
89
  unset($file_types[$eot_key]);
90
  }
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 => urldecode($variant->$file_type)] : []);
105
  }
106
 
107
  $stylesheet .= $this->build_source_string($font_src_url);
includes/frontend/class-functions.php CHANGED
@@ -80,8 +80,7 @@ class OMGF_Frontend_Functions
80
  * @since v4.5.3 Added 2nd dummy parameter, to prevent Fatal Errors after updating.
81
  */
82
  $pro_handle = apply_filters('omgf_pro_merged_handle', '', '');
83
-
84
- $i = 0;
85
 
86
  foreach ($optimized_fonts as $stylesheet_handle => $font_faces) {
87
  if ($pro_handle && $stylesheet_handle != $pro_handle) {
@@ -104,7 +103,7 @@ class OMGF_Frontend_Functions
104
  );
105
 
106
  foreach ($preload_variants as $variant) {
107
- $url = $variant->woff2;
108
  echo "<link id='omgf-preload-$i' rel='preload' href='$url' as='font' type='font/woff2' crossorigin />\n";
109
  $i++;
110
  }
@@ -130,7 +129,7 @@ class OMGF_Frontend_Functions
130
  add_action('wp_print_styles', [$this, 'remove_registered_fonts'], PHP_INT_MAX - 500);
131
  break;
132
  default:
133
- add_action('wp_print_styles', [$this, 'replace_registered_fonts'], PHP_INT_MAX - 500);
134
  }
135
  }
136
 
@@ -141,10 +140,10 @@ class OMGF_Frontend_Functions
141
  {
142
  global $wp_styles;
143
 
144
- $registered = $wp_styles->registered;
145
- $fonts = apply_filters('omgf_auto_remove', $this->detect_registered_google_fonts($registered));
146
 
147
- foreach ($fonts as $handle => $font) {
148
  $wp_styles->registered[$handle]->src = '';
149
  }
150
  }
@@ -152,16 +151,16 @@ class OMGF_Frontend_Functions
152
  /**
153
  * Retrieve stylesheets from Google Fonts' API and modify the stylesheet for local storage.
154
  */
155
- public function replace_registered_fonts()
156
  {
157
  global $wp_styles;
158
 
159
  $registered = $wp_styles->registered;
160
- $fonts = apply_filters('omgf_auto_replace', $this->detect_registered_google_fonts($registered));
161
- $unloaded_stylesheets = omgf_init()::unloaded_stylesheets();
162
- $unloaded_fonts = omgf_init()::unloaded_fonts();
163
 
164
- foreach ($fonts as $handle => $font) {
165
  // If this stylesheet has been marked for unload, empty the src and skip out early.
166
  if (in_array($handle, $unloaded_stylesheets)) {
167
  $wp_styles->registered[$handle]->src = '';
@@ -172,7 +171,7 @@ class OMGF_Frontend_Functions
172
  $updated_handle = $handle;
173
 
174
  if ($unloaded_fonts) {
175
- $updated_handle = omgf_init()::get_cache_key($handle);
176
  }
177
 
178
  $cached_file = OMGF_CACHE_PATH . '/' . $updated_handle . "/$updated_handle.css";
@@ -183,21 +182,35 @@ class OMGF_Frontend_Functions
183
  continue;
184
  }
185
 
 
 
 
 
 
 
186
  if (OMGF_OPTIMIZATION_MODE == 'manual' && isset($_GET['omgf_optimize'])) {
187
- $api_url = str_replace(['http:', 'https:'], '', home_url('/wp-json/omgf/v1/download/'));
188
- $protocol = '';
 
 
 
189
 
190
- if (substr($font->src, 0, 2) == '//') {
191
- $protocol = 'https:';
192
  }
193
 
194
- $params = http_build_query([
195
- 'handle' => $updated_handle,
196
- 'original_handle' => $handle,
197
- '_wpnonce' => wp_create_nonce('wp_rest')
198
- ]);
 
 
199
 
200
- $wp_styles->registered[$handle]->src = $protocol . str_replace('//fonts.googleapis.com/', $api_url, $font->src) . '&' . $params;
 
 
 
201
  }
202
  }
203
  }
@@ -207,13 +220,12 @@ class OMGF_Frontend_Functions
207
  *
208
  * @return array
209
  */
210
- private function detect_registered_google_fonts($registered_styles)
211
  {
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
  }
80
  * @since v4.5.3 Added 2nd dummy parameter, to prevent Fatal Errors after updating.
81
  */
82
  $pro_handle = apply_filters('omgf_pro_merged_handle', '', '');
83
+ $i = 0;
 
84
 
85
  foreach ($optimized_fonts as $stylesheet_handle => $font_faces) {
86
  if ($pro_handle && $stylesheet_handle != $pro_handle) {
103
  );
104
 
105
  foreach ($preload_variants as $variant) {
106
+ $url = rawurldecode($variant->woff2);
107
  echo "<link id='omgf-preload-$i' rel='preload' href='$url' as='font' type='font/woff2' crossorigin />\n";
108
  $i++;
109
  }
129
  add_action('wp_print_styles', [$this, 'remove_registered_fonts'], PHP_INT_MAX - 500);
130
  break;
131
  default:
132
+ add_action('wp_print_styles', [$this, 'replace_registered_stylesheets'], PHP_INT_MAX - 500);
133
  }
134
  }
135
 
140
  {
141
  global $wp_styles;
142
 
143
+ $registered = $wp_styles->registered;
144
+ $stylesheets = apply_filters('omgf_remove_detected_stylesheets', $this->detect_registered_stylesheets($registered));
145
 
146
+ foreach ($stylesheets as $handle => $stylesheet) {
147
  $wp_styles->registered[$handle]->src = '';
148
  }
149
  }
151
  /**
152
  * Retrieve stylesheets from Google Fonts' API and modify the stylesheet for local storage.
153
  */
154
+ public function replace_registered_stylesheets()
155
  {
156
  global $wp_styles;
157
 
158
  $registered = $wp_styles->registered;
159
+ $stylesheets = apply_filters('omgf_replace_detected_stylesheets', $this->detect_registered_stylesheets($registered));
160
+ $unloaded_stylesheets = OMGF::unloaded_stylesheets();
161
+ $unloaded_fonts = OMGF::unloaded_fonts();
162
 
163
+ foreach ($stylesheets as $handle => $stylesheet) {
164
  // If this stylesheet has been marked for unload, empty the src and skip out early.
165
  if (in_array($handle, $unloaded_stylesheets)) {
166
  $wp_styles->registered[$handle]->src = '';
171
  $updated_handle = $handle;
172
 
173
  if ($unloaded_fonts) {
174
+ $updated_handle = OMGF::get_cache_key($handle);
175
  }
176
 
177
  $cached_file = OMGF_CACHE_PATH . '/' . $updated_handle . "/$updated_handle.css";
182
  continue;
183
  }
184
 
185
+ /**
186
+ * For future reference: this logic can't be moved to backend, because there's no other way to properly access the
187
+ * $wp_styles global.
188
+ *
189
+ * @see $wp_styles global
190
+ */
191
  if (OMGF_OPTIMIZATION_MODE == 'manual' && isset($_GET['omgf_optimize'])) {
192
+ $request = parse_url($stylesheet->src);
193
+ $query = $request['query'] ?? '';
194
+ $path = $request['path'] ?? '/css';
195
+
196
+ parse_str($query, $query_array);
197
 
198
+ if (empty($query_array)) {
199
+ continue;
200
  }
201
 
202
+ $params = http_build_query(
203
+ $query_array + [
204
+ 'handle' => $updated_handle,
205
+ 'original_handle' => $handle,
206
+ '_wpnonce' => wp_create_nonce('wp_rest')
207
+ ]
208
+ );
209
 
210
+ /**
211
+ * Use Home URL directly while building API request. This might prevent local development (non-SSL) issues.
212
+ */
213
+ $wp_styles->registered[$handle]->src = home_url('/wp-json/omgf/v1/download') . $path . '?' . $params;
214
  }
215
  }
216
  }
220
  *
221
  * @return array
222
  */
223
+ private function detect_registered_stylesheets($registered_styles)
224
  {
225
  return array_filter(
226
  $registered_styles,
227
  function ($contents) {
228
+ return strpos($contents->src, 'fonts.googleapis.com/css') !== false;
 
229
  }
230
  );
231
  }
includes/optimization-mode/class-manual.php ADDED
@@ -0,0 +1,175 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_OptimizationMode_Manual
20
+ {
21
+ /** @var string */
22
+ private $plugin_text_domain = 'host-webfonts-local';
23
+
24
+ /**
25
+ * Build class.
26
+ *
27
+ * @return void
28
+ */
29
+ public function __construct()
30
+ {
31
+ $this->run();
32
+ }
33
+
34
+ /**
35
+ * Run Manual mode.
36
+ *
37
+ * @return void
38
+ */
39
+ private function run()
40
+ {
41
+ $url = esc_url_raw(OMGF_MANUAL_OPTIMIZE_URL);
42
+ $front_html = $this->remote_get($url);
43
+ $error = false;
44
+
45
+ if (is_wp_error($front_html) || wp_remote_retrieve_response_code($front_html) != 200) {
46
+ $this->frontend_fetch_failed($front_html);
47
+
48
+ $error = true;
49
+ }
50
+
51
+ $api_request_urls = [];
52
+ $document = new DOMDocument();
53
+
54
+ libxml_use_internal_errors(true);
55
+ @$document->loadHtml(wp_remote_retrieve_body($front_html));
56
+
57
+ foreach ($document->getElementsByTagName('link') as $link) {
58
+ /** @var DOMElement $link */
59
+ if ($link->hasAttribute('href') && strpos($link->getAttribute('href'), '/omgf/v1/download/')) {
60
+ $api_request_urls[] = $link->getAttribute('href');
61
+ }
62
+ }
63
+
64
+ if (empty($api_request_urls)) {
65
+ $this->no_urls_found();
66
+
67
+ $error = true;
68
+ }
69
+
70
+ foreach ($api_request_urls as $url) {
71
+ $download = $this->remote_get($url);
72
+
73
+ if (is_wp_error($download) || wp_remote_retrieve_response_code($download) != 200) {
74
+ $this->download_failed($download);
75
+
76
+ $error = true;
77
+ }
78
+ }
79
+
80
+ if (!$error) {
81
+ $this->optimization_succeeded();
82
+ }
83
+ }
84
+
85
+ /**
86
+ * @return void
87
+ */
88
+ private function optimization_succeeded()
89
+ {
90
+ add_settings_error('general', 'omgf_optimization_success', __('Optimization completed successfully.'), 'success');
91
+
92
+ OMGF_Admin_Notice::set_notice(
93
+ __('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),
94
+ 'omgf-cache-notice',
95
+ false,
96
+ 'warning'
97
+ );
98
+ }
99
+
100
+ /**
101
+ * @param $response WP_Error|array
102
+ */
103
+ private function download_failed($response)
104
+ {
105
+ add_settings_error('general', 'omgf_download_failed', __('OMGF encountered an error while downloading Google Fonts', $this->plugin_text_domain) . ': ' . $this->get_error_code($response) . ' - ' . $this->get_error_message($response), 'error');
106
+ }
107
+
108
+ /**
109
+ * @param $response WP_Error|array
110
+ */
111
+ private function frontend_fetch_failed($response)
112
+ {
113
+ add_settings_error('general', 'omgf_frontend_fetch_failed', __('OMGF encountered an error while fetching this site\'s frontend HTML', $this->plugin_text_domain) . ': ' . $this->get_error_code($response) . ' - ' . $this->get_error_message($response), 'error');
114
+ }
115
+
116
+ /**
117
+ * @return void
118
+ */
119
+ private function no_urls_found()
120
+ {
121
+ 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');
122
+ }
123
+
124
+ /**
125
+ * Wrapper for wp_remote_get() with preset params.
126
+ *
127
+ * @param mixed $url
128
+ * @return array|WP_Error
129
+ */
130
+ private function remote_get($url)
131
+ {
132
+ return wp_remote_get(
133
+ $this->no_cache_optimize_url($url),
134
+ [
135
+ 'timeout' => 30
136
+ ]
137
+ );
138
+ }
139
+
140
+ /**
141
+ * @param $url
142
+ *
143
+ * @return string
144
+ */
145
+ private function no_cache_optimize_url($url)
146
+ {
147
+ return add_query_arg(['omgf_optimize' => 1, 'nocache' => substr(md5(microtime()), rand(0, 26), 5)], $url);
148
+ }
149
+
150
+ /**
151
+ * @param array|WP_Error $response
152
+ * @return int|string
153
+ */
154
+ private function get_error_code($response)
155
+ {
156
+ if (is_wp_error($response)) {
157
+ return $response->get_error_code();
158
+ }
159
+
160
+ return wp_remote_retrieve_response_code($response);
161
+ }
162
+
163
+ /**
164
+ * @param array|WP_Error $response
165
+ * @return int|string
166
+ */
167
+ private function get_error_message($response)
168
+ {
169
+ if (is_wp_error($response)) {
170
+ return $response->get_error_message();
171
+ }
172
+
173
+ return wp_remote_retrieve_response_message($response);
174
+ }
175
+ }
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.5
7
  Requires PHP: 7.0
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
@@ -132,6 +132,13 @@ No, not yet. But I will definitely try to make it compatible in the future!
132
 
133
  == Changelog ==
134
 
 
 
 
 
 
 
 
135
  = 4.5.5 =
136
  * Fix: Prevent collision with other plugins when authenticating AJAX-calls.
137
 
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.6
7
  Requires PHP: 7.0
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
132
 
133
  == Changelog ==
134
 
135
+ = 4.5.6 =
136
+ * Fix: Added Fallback API URL for when Google Fonts Helper is down.
137
+ * Enhancement: Added extra error handling in Manual Optimization Mode.
138
+ * Fix: API requests made in Manual Optimization Mode are no longer forced to SSL. It now uses the protocol configured in Settings > General > WordPress URL.
139
+ * Fix: Stylesheet handles containing spaces would prevent Optimize Google Fonts screen from rendering properly.
140
+ * Several refactors and code optimizations.
141
+
142
  = 4.5.5 =
143
  * Fix: Prevent collision with other plugins when authenticating AJAX-calls.
144