font management fixes
This commit is contained in:
parent
847ed92c23
commit
d5ecb31dad
8 changed files with 728 additions and 99 deletions
|
|
@ -49,15 +49,17 @@ class MLF_Admin_Page {
|
|||
<div class="mlf-form-row">
|
||||
<label for="mlf-font-search"><?php esc_html_e('Search Fonts', 'maple-local-fonts'); ?></label>
|
||||
<div class="mlf-search-wrapper">
|
||||
<span class="dashicons dashicons-search mlf-search-icon"></span>
|
||||
<input type="text"
|
||||
id="mlf-font-search"
|
||||
class="mlf-search-input"
|
||||
placeholder="<?php esc_attr_e('Search Google Fonts...', 'maple-local-fonts'); ?>"
|
||||
placeholder="<?php esc_attr_e('Enter font name...', 'maple-local-fonts'); ?>"
|
||||
autocomplete="off" />
|
||||
<button type="button" class="button mlf-search-btn" id="mlf-search-btn">
|
||||
<?php esc_html_e('Search', 'maple-local-fonts'); ?>
|
||||
</button>
|
||||
<span class="spinner mlf-search-spinner" id="mlf-search-spinner"></span>
|
||||
</div>
|
||||
<p class="description"><?php esc_html_e('Type at least 2 characters to search.', 'maple-local-fonts'); ?></p>
|
||||
<p class="description"><?php esc_html_e('Enter at least 2 characters and click Search.', 'maple-local-fonts'); ?></p>
|
||||
</div>
|
||||
|
||||
<!-- Search Results -->
|
||||
|
|
@ -99,22 +101,32 @@ class MLF_Admin_Page {
|
|||
|
||||
<div class="mlf-info-note">
|
||||
<span class="dashicons dashicons-info-outline"></span>
|
||||
<span><?php esc_html_e('All font weights (100-900) will be downloaded automatically. Variable fonts are used when available for better performance.', 'maple-local-fonts'); ?></span>
|
||||
<span><?php esc_html_e('Weights 300-900 (Light to Black) will be downloaded. Variable fonts are used when available, which include all weights in a single efficient file.', 'maple-local-fonts'); ?></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Installed Fonts Section -->
|
||||
<div class="mlf-section mlf-installed-section">
|
||||
<h2><?php esc_html_e('Installed Fonts', 'maple-local-fonts'); ?></h2>
|
||||
<div class="mlf-section-header">
|
||||
<h2><?php esc_html_e('Installed Fonts', 'maple-local-fonts'); ?></h2>
|
||||
<?php if (!empty($installed_fonts)) : ?>
|
||||
<button type="button" class="button mlf-check-updates-btn" id="mlf-check-updates">
|
||||
<?php esc_html_e('Check for Updates', 'maple-local-fonts'); ?>
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<?php if (empty($installed_fonts)) : ?>
|
||||
<p class="mlf-no-fonts"><?php esc_html_e('No fonts installed yet. Search and select a font above to get started.', 'maple-local-fonts'); ?></p>
|
||||
<?php else : ?>
|
||||
<div id="mlf-font-list" class="mlf-font-list">
|
||||
<?php foreach ($installed_fonts as $font) : ?>
|
||||
<div class="mlf-font-item" data-font-id="<?php echo esc_attr($font['id']); ?>">
|
||||
<div class="mlf-font-item" data-font-id="<?php echo esc_attr($font['id']); ?>" data-font-name="<?php echo esc_attr($font['name']); ?>" data-font-version="<?php echo esc_attr($font['version']); ?>">
|
||||
<div class="mlf-font-info">
|
||||
<h3 class="mlf-font-name"><?php echo esc_html($font['name']); ?></h3>
|
||||
<div class="mlf-font-header">
|
||||
<h3 class="mlf-font-name"><?php echo esc_html($font['name']); ?></h3>
|
||||
<span class="mlf-update-badge" style="display: none;"><?php esc_html_e('Update available', 'maple-local-fonts'); ?></span>
|
||||
</div>
|
||||
<p class="mlf-font-variants">
|
||||
<?php
|
||||
$variant_strings = [];
|
||||
|
|
@ -124,8 +136,22 @@ class MLF_Admin_Page {
|
|||
echo esc_html(implode(', ', $variant_strings));
|
||||
?>
|
||||
</p>
|
||||
<p class="mlf-font-meta">
|
||||
<?php if (!empty($font['version'])) : ?>
|
||||
<span class="mlf-font-version"><?php echo esc_html($font['version']); ?></span>
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($font['last_modified'])) : ?>
|
||||
<span class="mlf-font-modified"><?php
|
||||
/* translators: %s: date */
|
||||
printf(esc_html__('Updated: %s', 'maple-local-fonts'), esc_html($font['last_modified']));
|
||||
?></span>
|
||||
<?php endif; ?>
|
||||
</p>
|
||||
</div>
|
||||
<div class="mlf-font-actions">
|
||||
<button type="button" class="button mlf-update-btn" data-font-id="<?php echo esc_attr($font['id']); ?>" data-font-name="<?php echo esc_attr($font['name']); ?>" style="display: none;">
|
||||
<?php esc_html_e('Update', 'maple-local-fonts'); ?>
|
||||
</button>
|
||||
<button type="button" class="button mlf-delete-btn" data-font-id="<?php echo esc_attr($font['id']); ?>">
|
||||
<?php esc_html_e('Delete', 'maple-local-fonts'); ?>
|
||||
</button>
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@ class MLF_Ajax_Handler {
|
|||
public function __construct() {
|
||||
add_action('wp_ajax_mlf_download_font', [$this, 'handle_download']);
|
||||
add_action('wp_ajax_mlf_delete_font', [$this, 'handle_delete']);
|
||||
add_action('wp_ajax_mlf_check_updates', [$this, 'handle_check_updates']);
|
||||
add_action('wp_ajax_mlf_update_font', [$this, 'handle_update_font']);
|
||||
// NEVER add wp_ajax_nopriv_ - admin only functionality
|
||||
|
||||
// Initialize rate limiter: 10 requests per minute
|
||||
|
|
@ -77,6 +79,10 @@ class MLF_Ajax_Handler {
|
|||
// Validate include_italic (boolean)
|
||||
$include_italic = isset($_POST['include_italic']) && $_POST['include_italic'] === '1';
|
||||
|
||||
// Get version info (optional)
|
||||
$font_version = isset($_POST['font_version']) ? sanitize_text_field(wp_unslash($_POST['font_version'])) : '';
|
||||
$font_last_modified = isset($_POST['font_last_modified']) ? sanitize_text_field(wp_unslash($_POST['font_last_modified'])) : '';
|
||||
|
||||
// 5. PROCESS REQUEST
|
||||
try {
|
||||
$downloader = new MLF_Font_Downloader();
|
||||
|
|
@ -91,7 +97,9 @@ class MLF_Ajax_Handler {
|
|||
$result = $registry->register_font(
|
||||
$download_result['font_name'],
|
||||
$download_result['font_slug'],
|
||||
$download_result['files']
|
||||
$download_result['files'],
|
||||
$font_version,
|
||||
$font_last_modified
|
||||
);
|
||||
|
||||
if (is_wp_error($result)) {
|
||||
|
|
@ -170,6 +178,166 @@ class MLF_Ajax_Handler {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle check for updates AJAX request.
|
||||
*/
|
||||
public function handle_check_updates() {
|
||||
// 1. NONCE CHECK
|
||||
if (!check_ajax_referer('mlf_check_updates', 'nonce', false)) {
|
||||
wp_send_json_error(['message' => __('Security check failed.', 'maple-local-fonts')], 403);
|
||||
}
|
||||
|
||||
// 2. CAPABILITY CHECK
|
||||
$capability = function_exists('mlf_get_capability') ? mlf_get_capability() : 'edit_theme_options';
|
||||
if (!current_user_can($capability)) {
|
||||
wp_send_json_error(['message' => __('Unauthorized.', 'maple-local-fonts')], 403);
|
||||
}
|
||||
|
||||
// 3. RATE LIMIT CHECK
|
||||
if (!$this->rate_limiter->check_and_record('check_updates')) {
|
||||
wp_send_json_error([
|
||||
'message' => __('Too many requests. Please wait a moment and try again.', 'maple-local-fonts'),
|
||||
], 429);
|
||||
}
|
||||
|
||||
// 4. GET INSTALLED FONTS AND CHECK VERSIONS
|
||||
try {
|
||||
$registry = new MLF_Font_Registry();
|
||||
$installed_fonts = $registry->get_imported_fonts();
|
||||
|
||||
if (empty($installed_fonts)) {
|
||||
wp_send_json_success(['updates' => []]);
|
||||
}
|
||||
|
||||
$font_search = new MLF_Font_Search();
|
||||
$updates = [];
|
||||
|
||||
foreach ($installed_fonts as $font) {
|
||||
$current_version = $font_search->get_font_version($font['name']);
|
||||
|
||||
if ($current_version && !empty($current_version['version'])) {
|
||||
$installed_version = $font['version'] ?? '';
|
||||
|
||||
// Compare versions
|
||||
if (!empty($installed_version) && $installed_version !== $current_version['version']) {
|
||||
$updates[$font['id']] = [
|
||||
'installed_version' => $installed_version,
|
||||
'latest_version' => $current_version['version'],
|
||||
'last_modified' => $current_version['lastModified'],
|
||||
];
|
||||
} elseif (empty($installed_version)) {
|
||||
// No version stored, consider it needs update
|
||||
$updates[$font['id']] = [
|
||||
'installed_version' => '',
|
||||
'latest_version' => $current_version['version'],
|
||||
'last_modified' => $current_version['lastModified'],
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wp_send_json_success(['updates' => $updates]);
|
||||
} catch (Exception $e) {
|
||||
error_log('MLF Check Updates Error: ' . sanitize_text_field($e->getMessage()));
|
||||
wp_send_json_error(['message' => __('An unexpected error occurred.', 'maple-local-fonts')]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle font update (re-download) AJAX request.
|
||||
*/
|
||||
public function handle_update_font() {
|
||||
// 1. NONCE CHECK
|
||||
if (!check_ajax_referer('mlf_update_font', 'nonce', false)) {
|
||||
wp_send_json_error(['message' => __('Security check failed.', 'maple-local-fonts')], 403);
|
||||
}
|
||||
|
||||
// 2. CAPABILITY CHECK
|
||||
$capability = function_exists('mlf_get_capability') ? mlf_get_capability() : 'edit_theme_options';
|
||||
if (!current_user_can($capability)) {
|
||||
wp_send_json_error(['message' => __('Unauthorized.', 'maple-local-fonts')], 403);
|
||||
}
|
||||
|
||||
// 3. RATE LIMIT CHECK
|
||||
if (!$this->rate_limiter->check_and_record('update')) {
|
||||
wp_send_json_error([
|
||||
'message' => __('Too many requests. Please wait a moment and try again.', 'maple-local-fonts'),
|
||||
], 429);
|
||||
}
|
||||
|
||||
// 4. INPUT VALIDATION
|
||||
$font_id = isset($_POST['font_id']) ? absint($_POST['font_id']) : 0;
|
||||
|
||||
if ($font_id < 1) {
|
||||
wp_send_json_error(['message' => __('Invalid font ID.', 'maple-local-fonts')]);
|
||||
}
|
||||
|
||||
// Verify font exists and is one we imported
|
||||
$font = get_post($font_id);
|
||||
if (!$font || $font->post_type !== 'wp_font_family') {
|
||||
wp_send_json_error(['message' => __('Font not found.', 'maple-local-fonts')]);
|
||||
}
|
||||
|
||||
if (get_post_meta($font_id, '_mlf_imported', true) !== '1') {
|
||||
wp_send_json_error(['message' => __('Cannot update fonts not imported by this plugin.', 'maple-local-fonts')]);
|
||||
}
|
||||
|
||||
// Get font name from post content
|
||||
$settings = json_decode($font->post_content, true);
|
||||
$font_name = $settings['name'] ?? $font->post_title;
|
||||
|
||||
// 5. DELETE OLD FONT AND RE-DOWNLOAD
|
||||
try {
|
||||
$registry = new MLF_Font_Registry();
|
||||
|
||||
// Delete old font
|
||||
$delete_result = $registry->delete_font($font_id);
|
||||
if (is_wp_error($delete_result)) {
|
||||
wp_send_json_error(['message' => $this->get_user_error_message($delete_result)]);
|
||||
}
|
||||
|
||||
// Get latest version info
|
||||
$font_search = new MLF_Font_Search();
|
||||
$version_info = $font_search->get_font_version($font_name);
|
||||
$font_version = $version_info['version'] ?? '';
|
||||
$font_last_modified = $version_info['lastModified'] ?? '';
|
||||
|
||||
// Re-download font (include italic by default)
|
||||
$downloader = new MLF_Font_Downloader();
|
||||
$download_result = $downloader->download($font_name, true);
|
||||
|
||||
if (is_wp_error($download_result)) {
|
||||
wp_send_json_error(['message' => $this->get_user_error_message($download_result)]);
|
||||
}
|
||||
|
||||
// Register font with new version info
|
||||
$result = $registry->register_font(
|
||||
$download_result['font_name'],
|
||||
$download_result['font_slug'],
|
||||
$download_result['files'],
|
||||
$font_version,
|
||||
$font_last_modified
|
||||
);
|
||||
|
||||
if (is_wp_error($result)) {
|
||||
wp_send_json_error(['message' => $this->get_user_error_message($result)]);
|
||||
}
|
||||
|
||||
wp_send_json_success([
|
||||
'message' => sprintf(
|
||||
/* translators: %s: font name */
|
||||
__('Successfully updated %s.', 'maple-local-fonts'),
|
||||
esc_html($font_name)
|
||||
),
|
||||
'font_id' => $result,
|
||||
'version' => $font_version,
|
||||
]);
|
||||
} catch (Exception $e) {
|
||||
error_log('MLF Update Font Error: ' . sanitize_text_field($e->getMessage()));
|
||||
wp_send_json_error(['message' => __('An unexpected error occurred.', 'maple-local-fonts')]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert internal error codes to user-friendly messages.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -25,11 +25,14 @@ class MLF_Font_Downloader {
|
|||
private $user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36';
|
||||
|
||||
/**
|
||||
* All available font weights.
|
||||
* Common font weights to request.
|
||||
*
|
||||
* Most fonts support at least 300-700. We also include 800-900 for fonts
|
||||
* that support Black/Heavy weights.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $all_weights = [100, 200, 300, 400, 500, 600, 700, 800, 900];
|
||||
private $all_weights = [300, 400, 500, 600, 700, 800, 900];
|
||||
|
||||
/**
|
||||
* Download a font from Google Fonts.
|
||||
|
|
@ -151,6 +154,8 @@ class MLF_Font_Downloader {
|
|||
/**
|
||||
* Download static fonts (fallback when variable not available).
|
||||
*
|
||||
* Tries different weight combinations since fonts support varying weights.
|
||||
*
|
||||
* @param string $font_name Font family name.
|
||||
* @param bool $include_italic Whether to include italic styles.
|
||||
* @return array|WP_Error Download result or error.
|
||||
|
|
@ -158,8 +163,28 @@ class MLF_Font_Downloader {
|
|||
private function download_static_fonts($font_name, $include_italic) {
|
||||
$styles = $include_italic ? ['normal', 'italic'] : ['normal'];
|
||||
|
||||
// Fetch CSS from Google
|
||||
$css = $this->fetch_static_css($font_name, $this->all_weights, $styles);
|
||||
// Try different weight combinations - fonts support varying weights
|
||||
$weight_sets = [
|
||||
[300, 400, 500, 600, 700, 800, 900], // Full range
|
||||
[300, 400, 500, 600, 700, 800], // Without 900
|
||||
[300, 400, 500, 600, 700], // Common range
|
||||
[400, 500, 600, 700], // Without light
|
||||
[400, 700], // Just regular and bold
|
||||
];
|
||||
|
||||
$css = null;
|
||||
foreach ($weight_sets as $weights) {
|
||||
$css = $this->fetch_static_css($font_name, $weights, $styles);
|
||||
|
||||
if (!is_wp_error($css)) {
|
||||
break;
|
||||
}
|
||||
|
||||
// If error is not "font not found", stop trying
|
||||
if ($css->get_error_code() !== 'font_not_found') {
|
||||
return $css;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_wp_error($css)) {
|
||||
return $css;
|
||||
|
|
@ -191,6 +216,9 @@ class MLF_Font_Downloader {
|
|||
/**
|
||||
* Fetch variable font CSS from Google Fonts API.
|
||||
*
|
||||
* Tries progressively smaller weight ranges until one works,
|
||||
* since different fonts support different weight ranges.
|
||||
*
|
||||
* @param string $font_name Font family name.
|
||||
* @param bool $italic Whether to fetch italic variant.
|
||||
* @return string|WP_Error CSS content or error.
|
||||
|
|
@ -198,15 +226,26 @@ class MLF_Font_Downloader {
|
|||
private function fetch_variable_css($font_name, $italic = false) {
|
||||
$family = str_replace(' ', '+', $font_name);
|
||||
|
||||
if ($italic) {
|
||||
// Request italic variable font
|
||||
$url = "https://fonts.googleapis.com/css2?family={$family}:ital,wght@1,100..900&display=swap";
|
||||
} else {
|
||||
// Request roman variable font
|
||||
$url = "https://fonts.googleapis.com/css2?family={$family}:wght@100..900&display=swap";
|
||||
// Try different weight ranges - fonts support varying ranges
|
||||
$weight_ranges = ['300..900', '300..800', '300..700', '400..700'];
|
||||
|
||||
foreach ($weight_ranges as $range) {
|
||||
if ($italic) {
|
||||
$url = "https://fonts.googleapis.com/css2?family={$family}:ital,wght@1,{$range}&display=swap";
|
||||
} else {
|
||||
$url = "https://fonts.googleapis.com/css2?family={$family}:wght@{$range}&display=swap";
|
||||
}
|
||||
|
||||
$result = $this->fetch_css($url);
|
||||
|
||||
// If successful or error is not "font not found", return
|
||||
if (!is_wp_error($result) || $result->get_error_code() !== 'font_not_found') {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->fetch_css($url);
|
||||
// All ranges failed
|
||||
return new WP_Error('no_variable', 'Variable font not available');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -19,12 +19,14 @@ class MLF_Font_Registry {
|
|||
/**
|
||||
* Register a font family with WordPress Font Library.
|
||||
*
|
||||
* @param string $font_name Display name (e.g., "Open Sans").
|
||||
* @param string $font_slug Slug (e.g., "open-sans").
|
||||
* @param array $files Array of downloaded file data.
|
||||
* @param string $font_name Display name (e.g., "Open Sans").
|
||||
* @param string $font_slug Slug (e.g., "open-sans").
|
||||
* @param array $files Array of downloaded file data.
|
||||
* @param string $font_version Google Fonts version (e.g., "v35").
|
||||
* @param string $last_modified Google Fonts last modified date.
|
||||
* @return int|WP_Error Font family post ID or error.
|
||||
*/
|
||||
public function register_font($font_name, $font_slug, $files) {
|
||||
public function register_font($font_name, $font_slug, $files, $font_version = '', $last_modified = '') {
|
||||
// Check if font already exists
|
||||
$existing = get_posts([
|
||||
'post_type' => 'wp_font_family',
|
||||
|
|
@ -88,6 +90,14 @@ class MLF_Font_Registry {
|
|||
update_post_meta($family_id, '_mlf_imported', '1');
|
||||
update_post_meta($family_id, '_mlf_import_date', current_time('mysql'));
|
||||
|
||||
// Store version info for update checking
|
||||
if (!empty($font_version)) {
|
||||
update_post_meta($family_id, '_mlf_font_version', $font_version);
|
||||
}
|
||||
if (!empty($last_modified)) {
|
||||
update_post_meta($family_id, '_mlf_font_last_modified', $last_modified);
|
||||
}
|
||||
|
||||
// Create font face posts (children) - WordPress also reads these
|
||||
foreach ($files as $file) {
|
||||
$filename = basename($file['path']);
|
||||
|
|
@ -190,6 +200,11 @@ class MLF_Font_Registry {
|
|||
delete_transient('global_styles');
|
||||
delete_transient('global_styles_' . get_stylesheet());
|
||||
|
||||
// Clear WP_Theme_JSON caches
|
||||
if (class_exists('WP_Theme_JSON_Resolver')) {
|
||||
WP_Theme_JSON_Resolver::clean_cached_data();
|
||||
}
|
||||
|
||||
// Clear object cache for post queries
|
||||
wp_cache_flush_group('posts');
|
||||
|
||||
|
|
@ -248,10 +263,14 @@ class MLF_Font_Registry {
|
|||
$faces_by_font[$parent_id][] = $face;
|
||||
}
|
||||
|
||||
// Batch get all import dates in single query
|
||||
// Batch get all metadata
|
||||
$import_dates = [];
|
||||
$font_versions = [];
|
||||
$font_last_modified = [];
|
||||
foreach ($font_ids as $font_id) {
|
||||
$import_dates[$font_id] = get_post_meta($font_id, '_mlf_import_date', true);
|
||||
$font_versions[$font_id] = get_post_meta($font_id, '_mlf_font_version', true);
|
||||
$font_last_modified[$font_id] = get_post_meta($font_id, '_mlf_font_last_modified', true);
|
||||
}
|
||||
|
||||
$result = [];
|
||||
|
|
@ -285,11 +304,13 @@ class MLF_Font_Registry {
|
|||
});
|
||||
|
||||
$result[] = [
|
||||
'id' => $font->ID,
|
||||
'name' => $settings['name'] ?? $font->post_title,
|
||||
'slug' => $settings['slug'] ?? $font->post_name,
|
||||
'variants' => $variants,
|
||||
'import_date' => $import_dates[$font->ID] ?? '',
|
||||
'id' => $font->ID,
|
||||
'name' => $settings['name'] ?? $font->post_title,
|
||||
'slug' => $settings['slug'] ?? $font->post_name,
|
||||
'variants' => $variants,
|
||||
'import_date' => $import_dates[$font->ID] ?? '',
|
||||
'version' => $font_versions[$font->ID] ?? '',
|
||||
'last_modified' => $font_last_modified[$font->ID] ?? '',
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -38,11 +38,13 @@ class MLF_Font_Search {
|
|||
const METADATA_URL = 'https://fonts.google.com/metadata/fonts';
|
||||
|
||||
/**
|
||||
* Maximum metadata response size (2MB).
|
||||
* Maximum metadata response size (10MB).
|
||||
*
|
||||
* Google Fonts metadata for 1500+ fonts can be 5-8MB.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const MAX_METADATA_SIZE = 2 * 1024 * 1024;
|
||||
const MAX_METADATA_SIZE = 10 * 1024 * 1024;
|
||||
|
||||
/**
|
||||
* Rate limiter instance.
|
||||
|
|
@ -165,10 +167,12 @@ class MLF_Font_Search {
|
|||
$fonts = [];
|
||||
foreach ($data['familyMetadataList'] as $font) {
|
||||
$fonts[] = [
|
||||
'family' => $font['family'],
|
||||
'category' => $font['category'] ?? 'sans-serif',
|
||||
'variants' => $font['fonts'] ?? [],
|
||||
'subsets' => $font['subsets'] ?? ['latin'],
|
||||
'family' => $font['family'],
|
||||
'category' => $font['category'] ?? 'sans-serif',
|
||||
'variants' => $font['fonts'] ?? [],
|
||||
'subsets' => $font['subsets'] ?? ['latin'],
|
||||
'version' => $font['version'] ?? '',
|
||||
'lastModified' => $font['lastModified'] ?? '',
|
||||
];
|
||||
}
|
||||
|
||||
|
|
@ -253,6 +257,8 @@ class MLF_Font_Search {
|
|||
'has_variable' => $has_variable,
|
||||
'has_italic' => $has_italic,
|
||||
'weights' => $weights,
|
||||
'version' => $font['version'] ?? '',
|
||||
'lastModified' => $font['lastModified'] ?? '',
|
||||
];
|
||||
}
|
||||
|
||||
|
|
@ -262,4 +268,31 @@ class MLF_Font_Search {
|
|||
public function clear_cache() {
|
||||
delete_transient(self::CACHE_KEY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get version info for a specific font.
|
||||
*
|
||||
* @param string $font_family Font family name.
|
||||
* @return array|null Version info or null if not found.
|
||||
*/
|
||||
public function get_font_version($font_family) {
|
||||
$fonts = $this->get_fonts_metadata();
|
||||
|
||||
if (is_wp_error($fonts)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$font_family_lower = strtolower($font_family);
|
||||
|
||||
foreach ($fonts as $font) {
|
||||
if (strtolower($font['family']) === $font_family_lower) {
|
||||
return [
|
||||
'version' => $font['version'] ?? '',
|
||||
'lastModified' => $font['lastModified'] ?? '',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue