Local Google Fonts - Version 0.1

Version Description

Download this release

Release Info

Developer everpress
Plugin Icon 128x128 Local Google Fonts
Version 0.1
Comparing to
See all releases

Version 0.1

README.md ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Local Google Fonts
2
+
3
+ Contributors: everpress
4
+ Tags: googlefonts, google, fonts, gdpr
5
+ Requires at least: 4.2
6
+ Tested up to: 5.9
7
+ Stable tag: 0.1
8
+ Requires PHP: 5.6+
9
+ License: GPLv2 or later
10
+ Author: EverPress
11
+ Author URI: https://everpress.co
12
+
13
+ ## Description
14
+
15
+ Host your used Google fonts on your server and make your site more GDPR compliant.
16
+
17
+ About 50 mio [\*](https://trends.builtwith.com/websitelist/Google-Font-API) sites use Google Fonts and in January 2022 a German court as ruled that using Google Fonts is a violation of Europe’s GDPR (General Data Protection Regulation).
18
+
19
+ more on [wptavern.com](https://wptavern.com/german-court-fines-website-owner-for-violating-the-gdpr-by-using-google-hosted-fonts)
20
+
21
+ ## Screenshots
22
+
23
+ ### 1. Option Interface.
24
+
25
+ ![Option Interface.](screenshot-1.png)
26
+
27
+ ### Features
28
+
29
+ 1. Quick install (activate, setup and forget)
30
+ 2. Automatically loads all used fonts to your server (wp-content/uploads)
31
+ 3. Cleanup on plugin deactivation
32
+ 4. Cleanup on plugin switch
33
+
34
+ ## Installation
35
+
36
+ 1. Upload the entire `local-google-fonts` folder to the `/wp-content/plugins/` directory
37
+ 2. Activate the plugin through the 'Plugins' menu in WordPress
38
+ 3. Go to Settings => Google Fonts and decide which fonts should get loaded locally
39
+
40
+ ## Changelog
41
+
42
+ ### 0.1
43
+
44
+ - initial release
assets/admin.js ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ jQuery(document).ready(function ($) {
2
+ 'use strict';
3
+
4
+ $('.host-locally').on('click', function () {
5
+ $(this).addClass('updating-message');
6
+ });
7
+ });
banner.png ADDED
Binary file
includes/class-local-google-fonts-admin.php ADDED
@@ -0,0 +1,191 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+
4
+ namespace EverPress;
5
+
6
+ class LGF_Admin {
7
+
8
+ private static $instance = null;
9
+
10
+ private function __construct() {
11
+
12
+ add_filter( 'admin_init', array( $this, 'register_settings' ) );
13
+ add_action( 'admin_menu', array( $this, 'settings_page' ) );
14
+
15
+ }
16
+
17
+ public static function get_instance() {
18
+ if ( self::$instance == null ) {
19
+ self::$instance = new LGF_Admin();
20
+ }
21
+
22
+ return self::$instance;
23
+ }
24
+
25
+ public function register_settings() {
26
+ register_setting( 'local_google_fonts', 'local_google_fonts', array( $this, 'local_google_fonts_validate' ) );
27
+ }
28
+
29
+ public function settings_page() {
30
+ $page = add_options_page( __( 'Google Fonts', 'local-google-fonts' ), __( 'Google Fonts', 'local-google-fonts' ), 'manage_options', 'lgf-settings', array( $this, 'render_settings' ) );
31
+ add_action( 'load-' . $page, array( &$this, 'script_styles' ) );
32
+
33
+ }
34
+
35
+ public function script_styles() {
36
+
37
+ $url = plugin_dir_url( LGF_PLUGIN_FILE ) . 'assets/admin.js';
38
+ $path = plugin_dir_path( LGF_PLUGIN_FILE ) . 'assets/admin.js';
39
+
40
+ wp_enqueue_script( 'local-google-fonts-admin', $url, array( 'jquery' ), filemtime( $path ), true );
41
+
42
+ }
43
+
44
+ public function local_google_fonts_validate() {
45
+
46
+ if ( ! isset( $_POST['hostlocal'] ) ) {
47
+ return;
48
+ }
49
+
50
+ $class = LGF::get_instance();
51
+
52
+ foreach ( $_POST['hostlocal'] as $handle => $url ) {
53
+ $class->process_url( $url, $handle );
54
+ }
55
+ }
56
+
57
+ public function get_font_info( $src ) {
58
+
59
+ $params = parse_url( $src );
60
+ parse_str( $params['query'], $args );
61
+ $args = wp_parse_args(
62
+ $args,
63
+ array(
64
+ 'subset' => null,
65
+ 'display' => 'fallback',
66
+ )
67
+ );
68
+
69
+ $groups = explode( '|', $args['family'] );
70
+
71
+ $fontinfo = array();
72
+ $families = array();
73
+ foreach ( $groups as $i => $group ) {
74
+ $parts = explode( ':', $group );
75
+ $fam = sanitize_title( str_replace( '+', '-', $parts[0] ) );
76
+ if ( ! isset( $families[ $fam ] ) ) {
77
+ $families[ $fam ] = array( 'regular' );
78
+ }
79
+ $families[ $fam ] = array_unique( array_merge( $families[ $fam ], explode( ',', $parts[1] ) ) );
80
+ sort( $families[ $fam ] );
81
+ }
82
+
83
+ foreach ( $families as $family => $variants ) {
84
+ $url = 'https://google-webfonts-helper.herokuapp.com/api/fonts/';
85
+ $the_url = add_query_arg(
86
+ array(
87
+ 'variants' => implode( ',', $variants ),
88
+ 'subset' => $args['subset'],
89
+ ),
90
+ $url . $family
91
+ );
92
+ $response = wp_remote_get( $the_url );
93
+ $code = wp_remote_retrieve_response_code( $response );
94
+
95
+ if ( 200 == $code ) {
96
+ $body = wp_remote_retrieve_body( $response );
97
+ $info = json_decode( $body );
98
+ $fontinfo[] = $info;
99
+
100
+ }
101
+ }
102
+
103
+ return $fontinfo;
104
+
105
+ }
106
+
107
+ public function render_settings() {
108
+
109
+ $buffer = get_option( 'local_google_fonts_buffer' );
110
+
111
+ if ( empty( $buffer ) ) {
112
+ return;
113
+ }
114
+
115
+ $folder = WP_CONTENT_DIR . '/uploads/fonts';
116
+ $folder_url = WP_CONTENT_URL . '/uploads/fonts';
117
+
118
+ ?>
119
+ <div class="wrap">
120
+ <h1><?php printf( __( '%d Google font sources found on your site.', 'local-google-fonts' ), count( $buffer ) ); ?></h1>
121
+ <form action="options.php" method="post">
122
+ <?php
123
+ settings_fields( 'local_google_fonts' );
124
+ do_settings_sections( 'local_google_fonts_section' );
125
+ ?>
126
+
127
+ <?php foreach ( $buffer as $handle => $data ) : ?>
128
+
129
+ <h2><?php esc_html_e( 'Handle', 'local-google-fonts' ); ?>: <code><?php esc_html_e( $handle ); ?></code></h2>
130
+
131
+
132
+ <table class="wp-list-table widefat fixed striped table-view-list ">
133
+ <thead>
134
+ <tr>
135
+ <th scope="col" id="name" class="manage-column column-name column-primary" style="width: 150px"><?php esc_html_e( 'Name', 'local-google-fonts' ); ?></th>
136
+ <th scope="col" id="description" class="manage-column column-description"><?php esc_html_e( 'Variants', 'local-google-fonts' ); ?></th>
137
+ <th scope="col" id="auto-updates" class="manage-column column-auto-updates" style="width: 250px"><?php esc_html_e( 'Status', 'local-google-fonts' ); ?></th>
138
+ </tr>
139
+ </thead>
140
+ <tbody>
141
+ <?php $fontinfo = $this->get_font_info( $data['src'] ); ?>
142
+
143
+ <?php foreach ( $fontinfo as $i => $set ) : ?>
144
+ <tr>
145
+ <td><strong><?php echo esc_html( $set->family ); ?></strong> <br>
146
+
147
+ </td>
148
+ <td>
149
+ <p class="code">
150
+ <?php foreach ( $set->variants as $variant ) : ?>
151
+
152
+ <?php printf( '%s %s', $variant->fontStyle, $variant->fontWeight ); ?>,
153
+ <?php endforeach ?>
154
+ </p>
155
+ <details>
156
+ <summary><strong><?php printf( '%d files from Google Servers', count( $set->variants ) * 5 ); ?></strong></summary>
157
+ <div style="max-height: 100px; overflow: scroll;font-size: small;white-space: nowrap; overflow: hidden; overflow-y: auto;" class="code">
158
+ <?php foreach ( $set->variants as $variant ) : ?>
159
+ <code><?php echo esc_url( $variant->woff2 ); ?></code><br>
160
+ <code><?php echo esc_url( $variant->ttf ); ?></code><br>
161
+ <code><?php echo esc_url( $variant->svg ); ?></code><br>
162
+ <code><?php echo esc_url( $variant->eot ); ?></code><br>
163
+ <code><?php echo esc_url( $variant->woff ); ?></code><br>
164
+ <?php endforeach ?>
165
+ </div>
166
+ </details>
167
+ </td>
168
+ <td>
169
+ <?php if ( is_dir( $folder . '/' . $data['id'] ) ) : ?>
170
+ <strong class="">✔</strong> loaded, served from your server
171
+ <?php else : ?>
172
+ <strong class="wp-ui-text-notification">✕</strong> not loaded, served from Google servers
173
+ <?php endif; ?>
174
+
175
+ </td>
176
+
177
+ </tr>
178
+ <?php endforeach ?>
179
+ </tbody>
180
+ </table>
181
+ <p>
182
+ <button class="host-locally button button-primary" name="hostlocal[<?php echo esc_attr( $handle ); ?>]" value="<?php echo esc_attr( $data['src'] ); ?>"><?php esc_html_e( 'Host locally', 'local-google-fonts' ); ?></button>
183
+ </p>
184
+ <?php endforeach ?>
185
+ </form>
186
+ </div>
187
+ <?php
188
+
189
+ }
190
+
191
+ }
includes/class-local-google-fonts.php ADDED
@@ -0,0 +1,163 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace EverPress;
4
+
5
+ class LGF {
6
+
7
+ private static $instance = null;
8
+
9
+ private $seed = AUTH_SALT;
10
+ private $upload_dir;
11
+
12
+ private function __construct() {
13
+
14
+ register_deactivation_hook( LGF_PLUGIN_FILE, array( $this, 'deactivate' ) );
15
+
16
+ add_filter( 'style_loader_src', array( $this, 'switch_stylesheet_src' ), 10, 2 );
17
+ add_filter( 'switch_theme', array( $this, 'clear' ), 10, 2 );
18
+
19
+ }
20
+
21
+ public static function get_instance() {
22
+ if ( self::$instance == null ) {
23
+ self::$instance = new LGF();
24
+ }
25
+
26
+ return self::$instance;
27
+ }
28
+
29
+
30
+
31
+ public function process_url( $src, $handle ) {
32
+
33
+ $id = md5( $src );
34
+ if ( ! function_exists( 'download_url' ) ) {
35
+ include ABSPATH . 'wp-admin/includes/file.php';
36
+ }
37
+
38
+ $WP_Filesystem = $this->wp_filesystem();
39
+
40
+ $style = "/* Font file served by Local Google Fonts Plugin */\n";
41
+
42
+ $urls[ $id ] = array();
43
+
44
+ $fontDisplay = 'fallback';
45
+
46
+ $folder = WP_CONTENT_DIR . '/uploads/fonts';
47
+ $folder_url = WP_CONTENT_URL . '/uploads/fonts';
48
+
49
+ $new_src = $folder_url . '/' . $id . '/font.css';
50
+ $new_dir = $folder . '/' . $id . '/font.css';
51
+
52
+ $class = LGF_Admin::get_instance();
53
+ $fontinfo = $class->get_font_info( $src );
54
+
55
+ foreach ( $fontinfo as $font ) {
56
+ $filename = $font->id . '-' . $font->version . '-' . $font->defSubset;
57
+ foreach ( $font->variants as $v ) {
58
+ $file = $filename . '-' . $v->id;
59
+
60
+ foreach ( array( 'woff', 'svg', 'woff2', 'ttf', 'eot' ) as $ext ) {
61
+
62
+ if ( ! is_dir( $folder . '/' . $id ) ) {
63
+ wp_mkdir_p( $folder . '/' . $id );
64
+ }
65
+ $tmp_file = download_url( $v->{$ext} );
66
+ $filepath = $folder . '/' . $id . '/' . $file . '.' . $ext;
67
+ $WP_Filesystem->copy( $tmp_file, $filepath );
68
+ $WP_Filesystem->delete( $tmp_file );
69
+
70
+ }
71
+
72
+ $style .= "@font-face {\n";
73
+ $style .= "\tfont-family: " . $v->fontFamily . ";\n";
74
+ $style .= "\tfont-style: " . $v->fontStyle . ";\n";
75
+ $style .= "\tfont-weight: " . $v->fontWeight . ";\n";
76
+ $style .= "\tfont-display: " . $fontDisplay . ";\n";
77
+ $style .= "\tsrc: url('" . $file . ".eot');\n";
78
+ $style .= "\tsrc: local(''),\n";
79
+ $style .= "\t url('" . $file . ".eot?#iefix') format('embedded-opentype'),\n";
80
+ $style .= "\t url('" . $file . ".woff2') format('woff2'),\n";
81
+ $style .= "\t url('" . $file . ".woff') format('woff'),\n";
82
+ $style .= "\t url('" . $file . ".ttf') format('truetype'),\n";
83
+ $style .= "\t url('" . $file . '.svg#' . $v->id . "') format('svg');\n";
84
+ $style .= "}\n\n";
85
+
86
+ }
87
+ }
88
+
89
+ $WP_Filesystem->put_contents( $new_dir, $style );
90
+
91
+ return $new_src !== $src;
92
+
93
+ }
94
+
95
+
96
+ public function google_to_local_url( $src, $handle ) {
97
+
98
+ $id = md5( $src );
99
+
100
+ $folder = WP_CONTENT_DIR . '/uploads/fonts';
101
+ $folder_url = WP_CONTENT_URL . '/uploads/fonts';
102
+
103
+ $new_dir = $folder . '/' . $id . '/font.css';
104
+
105
+ if ( ! file_exists( $new_dir ) ) {
106
+
107
+ $buffer = get_option( 'local_google_fonts_buffer' );
108
+ if ( empty( $buffer ) ) {
109
+ $buffer = array();
110
+ }
111
+ $buffer[ $handle ] = array(
112
+ 'id' => $id,
113
+ 'src' => $src,
114
+ );
115
+ update_option( 'local_google_fonts_buffer', $buffer );
116
+
117
+ } else {
118
+ $src = add_query_arg( 'v', filemtime( $new_dir ), $folder_url . '/' . $id . '/font.css' );
119
+ }
120
+
121
+ return $src;
122
+ }
123
+
124
+
125
+ public function switch_stylesheet_src( $src, $handle ) {
126
+
127
+ if ( false !== strpos( $src, '//fonts.googleapis.com/css' ) ) {
128
+ if ( ! is_customize_preview() ) {
129
+ $src = $this->google_to_local_url( $src, $handle );
130
+ }
131
+ }
132
+ return $src;
133
+ }
134
+
135
+
136
+ public function clear() {
137
+ $folder = WP_CONTENT_DIR . '/uploads/fonts';
138
+ if ( is_dir( $folder ) ) {
139
+ $WP_Filesystem = $this->wp_filesystem();
140
+ $WP_Filesystem->delete( $folder, true );
141
+ }
142
+ delete_option( 'local_google_fonts_buffer' );
143
+
144
+ }
145
+
146
+ private function wp_filesystem() {
147
+ global $wp_filesystem;
148
+
149
+ if ( ! function_exists( '\WP_Filesystem' ) ) {
150
+ include ABSPATH . 'wp-admin/includes/file.php';
151
+ }
152
+
153
+ \WP_Filesystem();
154
+
155
+ return $wp_filesystem;
156
+
157
+ }
158
+
159
+ public function deactivate() {
160
+ $this->clear();
161
+ }
162
+
163
+ }
local-google-fonts.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ Plugin Name: Local Google Fonts
4
+ Description: Host your used Google fonts on your server and make your site GDPR compliant.
5
+ Version: 0.1
6
+ Author: EverPress
7
+ Author URI: https://everpress.co
8
+ Text Domain: local-google-fonts
9
+ License: GPLv2 or later
10
+ */
11
+
12
+ namespace EverPress;
13
+
14
+ defined( 'ABSPATH' ) || exit;
15
+
16
+ if ( ! defined( 'LGF_PLUGIN_FILE' ) ) {
17
+ define( 'LGF_PLUGIN_FILE', __FILE__ );
18
+ }
19
+
20
+ if ( ! class_exists( 'EverPress\LGF' ) ) {
21
+ include_once 'includes/class-local-google-fonts.php';
22
+ include_once 'includes/class-local-google-fonts-admin.php';
23
+ }
24
+
25
+ add_action( 'plugins_loaded', array( 'EverPress\LGF', 'get_instance' ) );
26
+ add_action( 'plugins_loaded', array( 'EverPress\LGF_Admin', 'get_instance' ) );
local-google-fonts.zip ADDED
Binary file