PluginProbe
EasyFonts – Host Google Fonts Locally, Fast & Auto-Optimize, GDPR Compliant / trunk
EasyFonts – Host Google Fonts Locally, Fast & Auto-Optimize, GDPR Compliant vtrunk
2.0.3 2.0.2 2.0.1 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.2 1.3 2.0.0
easyfonts / easyfonts.php

easyfonts.php in EasyFonts – Host Google Fonts Locally, Fast & Auto-Optimize, GDPR Compliant trunk, at easyfonts.php

205 lines 5.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Plugin Name: Easy Fonts
4 * Plugin URI: https://fluxpress.io
5 * Description: Detect, self-host, preload, and trim Google Fonts automatically — reliably, with zero-CLS metric-matched fallbacks. Built on WordPress's native HTML API.
6 * Version: 2.0.3
7 * Author: Uzair
8 * Author URI: https://fluxpress.io
9 * License: GPL-2.0-or-later
10 * License URI: https://www.gnu.org/licenses/gpl-2.0.html
11 * Text Domain: easyfonts
12 * Domain Path: /languages
13 * Requires at least: 6.4
14 * Requires PHP: 7.4
15 *
16 * @package EasyFonts
17 */
18
19 defined( 'ABSPATH' ) || exit;
20
21 define( 'EASYFONTS_VERSION', '2.0.3' );
22 define( 'EASYFONTS_FILE', __FILE__ );
23 define( 'EASYFONTS_DIR', plugin_dir_path( __FILE__ ) );
24 define( 'EASYFONTS_URL', plugin_dir_url( __FILE__ ) );
25 define( 'EASYFONTS_BASENAME', plugin_basename( __FILE__ ) );
26
27 /**
28 * PHP 7.4 polyfills. The plugin advertises "Requires PHP: 7.4", but parts of the
29 * codebase use string helpers added in PHP 8.0. These guarded shims keep it
30 * genuinely 7.4-compatible without changing any call sites.
31 */
32 if ( ! function_exists( 'str_starts_with' ) ) {
33 function str_starts_with( $haystack, $needle ): bool {
34 return '' === $needle || 0 === strncmp( (string) $haystack, (string) $needle, strlen( (string) $needle ) );
35 }
36 }
37 if ( ! function_exists( 'str_ends_with' ) ) {
38 function str_ends_with( $haystack, $needle ): bool {
39 if ( '' === $needle ) {
40 return true;
41 }
42 $len = strlen( (string) $needle );
43 return $len <= strlen( (string) $haystack ) && 0 === substr_compare( (string) $haystack, (string) $needle, -$len );
44 }
45 }
46 if ( ! function_exists( 'str_contains' ) ) {
47 function str_contains( $haystack, $needle ): bool {
48 return '' === $needle || false !== strpos( (string) $haystack, (string) $needle );
49 }
50 }
51
52 /**
53 * PSR-4 autoloader for the EasyFonts\ namespace.
54 */
55 spl_autoload_register(
56 static function ( $class ) {
57 $prefix = 'EasyFonts\\';
58 $len = strlen( $prefix );
59
60 if ( 0 !== strncmp( $prefix, $class, $len ) ) {
61 return;
62 }
63
64 $relative = substr( $class, $len );
65 $path = EASYFONTS_DIR . 'src/' . str_replace( '\\', '/', $relative ) . '.php';
66
67 if ( is_readable( $path ) ) {
68 require_once $path;
69 }
70 }
71 );
72
73 /**
74 * Resolve the upload directory + URL once. Scheme-correct, multisite-safe.
75 *
76 * @return array{path:string,url:string}
77 */
78 function easyfonts_paths(): array {
79 static $paths = null;
80
81 if ( null === $paths ) {
82 $upload = wp_upload_dir();
83 $paths = array(
84 'path' => trailingslashit( $upload['basedir'] ) . 'easyfonts',
85 'url' => set_url_scheme( trailingslashit( $upload['baseurl'] ) . 'easyfonts' ),
86 );
87 }
88
89 return $paths;
90 }
91
92 /**
93 * Boot the plugin on plugins_loaded.
94 */
95 add_action(
96 'plugins_loaded',
97 static function () {
98 $paths = easyfonts_paths();
99
100 if ( ! defined( 'EASYFONTS_CACHE_DIR' ) ) {
101 define( 'EASYFONTS_CACHE_DIR', $paths['path'] );
102 }
103 if ( ! defined( 'EASYFONTS_CACHE_URL' ) ) {
104 define( 'EASYFONTS_CACHE_URL', $paths['url'] );
105 }
106
107 \EasyFonts\Plugin::instance();
108 }
109 );
110
111 /**
112 * WP-CLI registration (loaded outside the normal request lifecycle).
113 */
114 if ( defined( 'WP_CLI' ) && WP_CLI ) {
115 add_action(
116 'cli_init',
117 static function () {
118 \WP_CLI::add_command( 'easyfonts', \EasyFonts\Cli\Command::class );
119 }
120 );
121 }
122
123 /**
124 * Activation — create tables, seed defaults, mark for rewrite.
125 *
126 * On multisite the activation hook fires once even for a network-wide enable,
127 * so when network-activated we install on every existing site. New sites
128 * created later are handled by the wp_initialize_site hook below, and any site
129 * that somehow slips through self-heals on its first load (Plugin::maybe_migrate).
130 *
131 * @param bool $network_wide Whether the plugin is being network-activated.
132 */
133 register_activation_hook(
134 __FILE__,
135 static function ( $network_wide = false ) {
136 require_once EASYFONTS_DIR . 'src/Database/Migrator.php';
137
138 $install = static function () {
139 ( new \EasyFonts\Database\Migrator() )->install();
140 add_option( 'easyfonts_activated_at', time() );
141 };
142
143 if ( is_multisite() && $network_wide ) {
144 $site_ids = get_sites( array( 'fields' => 'ids', 'number' => 0 ) );
145
146 foreach ( $site_ids as $site_id ) {
147 switch_to_blog( (int) $site_id );
148 $install();
149 restore_current_blog();
150 }
151
152 return;
153 }
154
155 $install();
156 }
157 );
158
159 /**
160 * Multisite: install tables when a brand-new subsite is created, if the plugin
161 * is network-active. (WP 5.1+ passes a WP_Site; older signatures are tolerated.)
162 *
163 * @param mixed $site New site (WP_Site) or blog id.
164 */
165 add_action(
166 'wp_initialize_site',
167 static function ( $site ) {
168 if ( ! is_multisite() ) {
169 return;
170 }
171
172 if ( ! function_exists( 'is_plugin_active_for_network' ) ) {
173 require_once ABSPATH . 'wp-admin/includes/plugin.php';
174 }
175
176 if ( ! is_plugin_active_for_network( EASYFONTS_BASENAME ) ) {
177 return;
178 }
179
180 $blog_id = is_object( $site ) && isset( $site->blog_id ) ? (int) $site->blog_id : (int) $site;
181
182 if ( $blog_id <= 0 ) {
183 return;
184 }
185
186 require_once EASYFONTS_DIR . 'src/Database/Migrator.php';
187
188 switch_to_blog( $blog_id );
189 ( new \EasyFonts\Database\Migrator() )->install();
190 restore_current_blog();
191 },
192 10,
193 1
194 );
195
196 /**
197 * Deactivation — clear scheduled events.
198 */
199 register_deactivation_hook(
200 __FILE__,
201 static function () {
202 wp_clear_scheduled_hook( 'easyfonts_cleanup' );
203 }
204 );
205