PluginProbe ʕ •ᴥ•ʔ
Kirki – Freeform Page Builder, Website Builder & Customizer / 6.0.13
Kirki – Freeform Page Builder, Website Builder & Customizer v6.0.13
6.1.1 6.1.0 6.0.14 6.0.13 6.0.12 6.0.11 6.0.10 6.0.9 6.0.8 6.0.7 6.0.6 6.0.5 6.0.4 6.0.3 6.0.2 6.0.1 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 3.1.8 3.1.9 4.0.19 4.0.20 4.0.21 4.0.22 4.0.23 4.0.24 4.1 4.2.0 5.0.0 5.1.0 5.1.1 5.2.0 5.2.1 5.2.2 5.2.3 6.0.0 trunk 3.0.40 3.0.41 3.0.42 3.0.43 3.0.44 3.0.45 3.1.0 3.1.1 3.1.2
kirki / customizer / packages / modules / webfonts / src / Webfonts / Embed.php
kirki / customizer / packages / modules / webfonts / src / Webfonts Last commit date
Async.php 2 months ago Downloader.php 5 months ago Embed.php 2 months ago Fonts.php 5 months ago Google.php 2 months ago
Embed.php
200 lines
1 <?php
2 /**
3 * Adds the Webfont Loader to load fonts asynchronously.
4 *
5 * @package kirki-framework/module-webfonts
6 * @author Themeum
7 * @copyright Copyright (c) 2023, Themeum
8 * @license https://opensource.org/licenses/MIT
9 * @since 1.0.0
10 */
11
12 namespace Kirki\Module\Webfonts;
13
14 if ( ! defined( 'ABSPATH' ) ) {
15 exit;
16 }
17
18 use Kirki\Module\Webfonts\Helper;
19
20 /**
21 * Manages the way Google Fonts are enqueued.
22 */
23 final class Embed {
24
25 /**
26 * The config ID.
27 *
28 * @access protected
29 * @since 1.0.0
30 * @var string
31 */
32 protected $config_id;
33
34 /**
35 * The \Kirki\Module\Webfonts object.
36 *
37 * @access protected
38 * @since 1.0.0
39 * @var object
40 */
41 protected $webfonts;
42
43 /**
44 * The \Kirki\Module\Webfonts\Google object.
45 *
46 * @access protected
47 * @since 1.0.0
48 * @var object
49 */
50 protected $googlefonts;
51
52 /**
53 * Fonts to load.
54 *
55 * @access protected
56 * @since 1.0.0
57 * @var array
58 */
59 protected $fonts_to_load = [];
60
61 /**
62 * Constructor.
63 *
64 * @access public
65 * @since 1.0.0
66 * @param string $config_id The config-ID.
67 * @param object $webfonts The \Kirki\Module\Webfonts object.
68 * @param object $googlefonts The \Kirki\Module\Webfonts\Google object.
69 * @param array $args Extra args we want to pass.
70 */
71 public function __construct( $config_id, $webfonts, $googlefonts, $args = [] ) {
72 $this->config_id = $config_id;
73 $this->webfonts = $webfonts;
74 $this->googlefonts = $googlefonts;
75
76 add_action( 'wp', [ $this, 'init' ], 9 );
77 // add_filter( 'wp_resource_hints', [ $this, 'resource_hints' ], 10, 2 );
78 }
79
80 /**
81 * Init.
82 *
83 * @access public
84 * @since 1.0.0
85 * @return void
86 */
87 public function init() {
88 $this->populate_fonts();
89 add_action( 'kirki_dynamic_css', [ $this, 'the_css' ] );
90 }
91
92 /**
93 * Add preconnect for Google Fonts.
94 *
95 * @access public
96 * @param array $urls URLs to print for resource hints.
97 * @param string $relation_type The relation type the URLs are printed.
98 * @return array $urls URLs to print for resource hints.
99 */
100 public function resource_hints( $urls, $relation_type ) {
101 $fonts_to_load = $this->googlefonts->fonts;
102
103 if ( ! empty( $fonts_to_load ) && 'preconnect' === $relation_type ) {
104 $urls[] = [
105 'href' => 'https://fonts.gstatic.com',
106 'crossorigin',
107 ];
108 }
109
110 return $urls;
111 }
112
113 /**
114 * Webfont Loader for Google Fonts.
115 *
116 * @access public
117 * @since 1.0.0
118 */
119 public function populate_fonts() {
120
121 // Go through our fields and populate $this->fonts.
122 $this->webfonts->loop_fields( $this->config_id );
123
124 $this->googlefonts->fonts = apply_filters( 'kirki_enqueue_google_fonts', $this->googlefonts->fonts );
125
126 // Goes through $this->fonts and adds or removes things as needed.
127 $this->googlefonts->process_fonts();
128
129 foreach ( $this->googlefonts->fonts as $font => $weights ) {
130 foreach ( $weights as $key => $value ) {
131 if ( 'italic' === $value ) {
132 $weights[ $key ] = '400i';
133 } else {
134 $weights[ $key ] = str_replace( [ 'regular', 'bold', 'italic' ], [ '400', '', 'i' ], $value );
135 }
136 }
137 $this->fonts_to_load[] = [
138 'family' => $font,
139 'weights' => $weights,
140 ];
141 }
142 }
143
144 /**
145 * Webfont Loader script for Google Fonts.
146 *
147 * @access public
148 * @since 1.0.0
149 */
150 public function the_css() {
151 foreach ( $this->fonts_to_load as $font ) {
152
153 $family = str_replace( ' ', '+', trim( $font['family'] ) );
154 $weights = join( ',', $font['weights'] );
155 $subset = apply_filters( 'kirki_googlefonts_subset', 'cyrillic,cyrillic-ext,devanagari,greek,greek-ext,khmer,latin,latin-ext,vietnamese,hebrew,arabic,bengali,gujarati,tamil,telugu,thai' );
156 $url = "https://fonts.googleapis.com/css?family={$family}:{$weights}&subset={$subset}&display=swap";
157
158 $downloader = new Downloader();
159 $contents = $downloader->get_styles( $url );
160
161 if ( $contents ) {
162 /**
163 * Note to code reviewers:
164 *
165 * Though all output should be run through an escaping function, this is pure CSS
166 * and it is added on a call that has a PHP `header( 'Content-type: text/css' );`.
167 * No code, script or anything else can be executed from inside a stylesheet.
168 * For extra security we're using the wp_strip_all_tags() function here
169 * just to make sure there's no <script> tags in there or anything else.
170 */
171 echo wp_strip_all_tags( $contents ); // phpcs:ignore WordPress.Security.EscapeOutput
172 }
173 }
174 }
175
176 /**
177 * Downloads font-files locally and uses the local files instead of the ones from Google's servers.
178 * This addresses any and all GDPR concerns, as well as firewalls that exist in some parts of the world.
179 *
180 * @access private
181 * @since 1.0.0
182 * @param string $css The CSS with original URLs.
183 * @return string The CSS with local URLs.
184 */
185 private function use_local_files( $css ) {
186 preg_match_all( '/https\:.*?\.woff/', $css, $matches );
187
188 $matches = array_shift( $matches );
189
190 foreach ( $matches as $match ) {
191 if ( 0 === strpos( $match, 'https://fonts.gstatic.com' ) ) {
192 $new_url = Helper::download_font_file( $match );
193 if ( $new_url ) {
194 $css = str_replace( $match, $new_url, $css );
195 }
196 }
197 }
198 return $css;
199 }
200 }