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 | 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 +1 -1
- includes/admin/settings/class-builder.php +2 -2
- includes/admin/settings/class-detection.php +1 -1
- includes/admin/settings/class-optimize.php +6 -8
- includes/api/class-download.php +66 -14
- includes/class-admin.php +16 -6
- includes/class-ajax.php +1 -0
- includes/class-download.php +1 -1
- includes/class-omgf.php +9 -0
- includes/class-optimize.php +10 -108
- includes/class-stylesheet-generator.php +3 -3
- includes/frontend/class-functions.php +38 -26
- includes/optimization-mode/class-manual.php +175 -0
- readme.txt +8 -1
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.
|
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 |
|
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 |
|
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 =
|
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 =
|
200 |
?>
|
201 |
<?php foreach ($this->optimized_fonts as $handle => $fonts) : ?>
|
202 |
<?php
|
203 |
-
if (!
|
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=
|
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
|
|
|
|
|
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 =
|
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 =
|
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
|
327 |
$font_family = str_replace('-', ' ', $family);
|
328 |
-
$
|
|
|
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 |
-
|
333 |
-
|
334 |
-
|
335 |
-
'error'
|
336 |
-
);
|
337 |
|
338 |
-
|
|
|
|
|
|
|
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 ($
|
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, '
|
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
|
145 |
*/
|
146 |
-
public function
|
147 |
{
|
148 |
-
return $
|
149 |
}
|
150 |
|
151 |
/**
|
@@ -203,7 +205,15 @@ class OMGF_Admin
|
|
203 |
$wp_settings_errors = [];
|
204 |
}
|
205 |
|
206 |
-
add_settings_error(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
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
|
81 |
*/
|
82 |
public function verify_ssl($args)
|
83 |
{
|
@@ -87,107 +84,12 @@ class OMGF_Optimize
|
|
87 |
}
|
88 |
|
89 |
/**
|
90 |
-
*
|
|
|
|
|
91 |
*/
|
92 |
private function run_manual()
|
93 |
{
|
94 |
-
|
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, '
|
134 |
}
|
135 |
}
|
136 |
|
@@ -141,10 +140,10 @@ class OMGF_Frontend_Functions
|
|
141 |
{
|
142 |
global $wp_styles;
|
143 |
|
144 |
-
$registered
|
145 |
-
$
|
146 |
|
147 |
-
foreach ($
|
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
|
156 |
{
|
157 |
global $wp_styles;
|
158 |
|
159 |
$registered = $wp_styles->registered;
|
160 |
-
$
|
161 |
-
$unloaded_stylesheets =
|
162 |
-
$unloaded_fonts =
|
163 |
|
164 |
-
foreach ($
|
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 =
|
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 |
-
$
|
188 |
-
$
|
|
|
|
|
|
|
189 |
|
190 |
-
if (
|
191 |
-
|
192 |
}
|
193 |
|
194 |
-
$params = http_build_query(
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
|
|
|
|
199 |
|
200 |
-
|
|
|
|
|
|
|
201 |
}
|
202 |
}
|
203 |
}
|
@@ -207,13 +220,12 @@ class OMGF_Frontend_Functions
|
|
207 |
*
|
208 |
* @return array
|
209 |
*/
|
210 |
-
private function
|
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.
|
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 |
|