/ and loaded from there. Visitors' browsers never contact Google (GDPR). */ defined( 'ABSPATH' ) || exit; /** * Fonts to choose from: family => fallback. */ function runline_google_fonts() { return apply_filters( 'runline_google_fonts', array( 'Inter' => 'sans-serif', 'Roboto' => 'sans-serif', 'Open Sans' => 'sans-serif', 'Montserrat' => 'sans-serif', 'Poppins' => 'sans-serif', 'Lato' => 'sans-serif', 'Nunito' => 'sans-serif', 'Raleway' => 'sans-serif', 'Rubik' => 'sans-serif', 'Work Sans' => 'sans-serif', 'DM Sans' => 'sans-serif', 'Manrope' => 'sans-serif', 'Space Grotesk' => 'sans-serif', 'Oswald' => 'sans-serif', 'Bebas Neue' => 'sans-serif', 'Anton' => 'sans-serif', 'Playfair Display' => 'serif', 'Merriweather' => 'serif', 'Lobster' => 'cursive', 'Pacifico' => 'cursive', ) ); } /** * Family of a "g:" font choice, or "" for the other fonts. */ function runline_google_family( $font ) { if ( 0 !== strpos( (string) $font, 'g:' ) ) { return ''; } $family = substr( $font, 2 ); return isset( runline_google_fonts()[ $family ] ) ? $family : ''; } function runline_font_slug( $family ) { return sanitize_title( $family ); } /** * Folder and URL of the local copies. */ function runline_fonts_dir() { $uploads = wp_upload_dir( null, false ); return array( 'dir' => trailingslashit( $uploads['basedir'] ) . 'runline-fonts', 'url' => trailingslashit( $uploads['baseurl'] ) . 'runline-fonts', ); } /** * URL of the local CSS of a font ("" while it is not downloaded). */ function runline_font_css_url( $family ) { $base = runline_fonts_dir(); $slug = runline_font_slug( $family ); return file_exists( $base['dir'] . '/' . $slug . '/font.css' ) ? $base['url'] . '/' . $slug . '/font.css' : ''; } /** * Downloads a font (CSS + woff2 files) once. Runs in the admin when a bar with this font is saved or previewed. * * @param string $family Font family. * @return string URL of the local CSS, or "" on failure. */ function runline_font_download( $family ) { if ( ! isset( runline_google_fonts()[ $family ] ) ) { return ''; } $ready = runline_font_css_url( $family ); if ( $ready ) { return $ready; } $base = runline_fonts_dir(); $slug = runline_font_slug( $family ); $folder = $base['dir'] . '/' . $slug; $url = 'https://fonts.googleapis.com/css2?family=' . rawurlencode( $family ) . ':wght@400;500;600;700;800&display=swap'; // A current browser gets woff2 files. $answer = wp_remote_get( $url, array( 'timeout' => 20, 'user-agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0 Safari/537.36', ) ); if ( is_wp_error( $answer ) || 200 !== wp_remote_retrieve_response_code( $answer ) ) { // Fonts without some of the weights: ask for the regular one. $answer = wp_remote_get( str_replace( ':wght@400;500;600;700;800', '', $url ), array( 'timeout' => 20, 'user-agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0 Safari/537.36', ) ); if ( is_wp_error( $answer ) || 200 !== wp_remote_retrieve_response_code( $answer ) ) { return ''; } } $css = wp_remote_retrieve_body( $answer ); if ( ! preg_match_all( '#url\((https://fonts\.gstatic\.com/[^)]+\.woff2)\)#', $css, $files ) ) { return ''; } if ( ! wp_mkdir_p( $folder ) ) { return ''; } foreach ( array_unique( $files[1] ) as $i => $remote ) { $name = $slug . '-' . $i . '.woff2'; $file = wp_remote_get( $remote, array( 'timeout' => 20 ) ); if ( is_wp_error( $file ) || 200 !== wp_remote_retrieve_response_code( $file ) ) { return ''; } file_put_contents( $folder . '/' . $name, wp_remote_retrieve_body( $file ) ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_file_put_contents -- a font file into uploads. $css = str_replace( $remote, $name, $css ); } file_put_contents( $folder . '/font.css', $css ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_file_put_contents -- the font CSS into uploads. return runline_font_css_url( $family ); } /** * Loads the local font of a bar on the page. * * @param array $settings Bar settings. */ function runline_enqueue_font( $settings ) { $family = runline_google_family( $settings['font'] ); $url = $family ? runline_font_css_url( $family ) : ''; if ( $url ) { wp_enqueue_style( 'runline-font-' . runline_font_slug( $family ), $url, array(), RUNLINE_VERSION ); } } // Saving a bar downloads its font. add_action( 'runline_settings_saved', function ( $bar_id, $settings ) { $family = runline_google_family( $settings['font'] ); if ( $family ) { runline_font_download( $family ); } }, 10, 2 );