Plugin Directory

Changeset 3388720


Ignore:
Timestamp:
11/03/2025 09:35:02 AM (4 months ago)
Author:
chrmrtns
Message:

Release version 1.1.2

Fix Gutenberg font display issue

Changes in v1.1.2:

  • Fix: Fonts now display correctly in Gutenberg block editor
  • NEW: Generate .has-{slug}-font-family CSS classes for Gutenberg typography controls
  • NEW: Intelligent font fallback detection (serif, sans-serif, monospace, cursive)
  • Fix: Database migration now properly adds family_slug column for users upgrading from v1.0.x
  • Improved: Enhanced error handling for font uploads with detailed error messages
  • Improved: Better directory writability checks before file operations
  • Technical: Added PHPCS ignore comments for legitimate direct filesystem operations
Location:
safefonts
Files:
6 edited
9 copied

Legend:

Unmodified
Added
Removed
  • safefonts/tags/1.1.2/includes/Core.php

    r3388505 r3388720  
    350350        require_once ABSPATH . 'wp-admin/includes/upgrade.php';
    351351        dbDelta($sql);
     352
     353        // Migration check: Add family_slug column if it doesn't exist (v1.1.0+)
     354        $columns = $wpdb->get_col("DESCRIBE {$table_name}"); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Migration check, runs once on activation
     355        if (!in_array('family_slug', $columns, true)) {
     356            $wpdb->query("ALTER TABLE {$table_name} ADD COLUMN family_slug varchar(255) NOT NULL DEFAULT '' AFTER font_family"); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Adding missing column for migration
     357            $wpdb->query("ALTER TABLE {$table_name} ADD KEY family_slug (family_slug)"); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Adding index for new column
     358        }
    352359
    353360        // Always check for fonts needing migration (v1.1.0+)
  • safefonts/tags/1.1.2/includes/FontManager.php

    r3388505 r3388720  
    101101        $css = "/* SafeFonts - Generated CSS */\n";
    102102        $css .= "/* Generated: " . current_time('mysql') . " */\n\n";
     103        $css .= "/* ================================= */\n";
     104        $css .= "/*   FONT FACE DECLARATIONS         */\n";
     105        $css .= "/* ================================= */\n\n";
    103106
    104107        foreach ($fonts as $font) {
     
    116119        }
    117120
     121        // Generate Gutenberg CSS classes
     122        $css .= "/* ================================= */\n";
     123        $css .= "/*   GUTENBERG FONT FAMILY CLASSES  */\n";
     124        $css .= "/* ================================= */\n\n";
     125
     126        $fonts_by_family = $this->get_fonts_by_family();
     127        foreach ($fonts_by_family as $family => $variants) {
     128            $slug = sanitize_title($family);
     129            $fallback = $this->get_font_fallback($family);
     130
     131            $css .= ".has-" . $slug . "-font-family {\n";
     132            $css .= "  font-family: '" . esc_attr($family) . "'" . $fallback . ";\n";
     133            $css .= "}\n\n";
     134        }
     135
    118136        return $css;
    119137    }
     
    144162        $family_dir = SAFEFONTS_ASSETS_DIR . $family_slug . '/';
    145163        if (!file_exists($family_dir)) {
    146             wp_mkdir_p($family_dir);
     164            if (!wp_mkdir_p($family_dir)) {
     165                return new \WP_Error('mkdir_failed', __('Failed to create font family directory.', 'safefonts'));
     166            }
     167        }
     168
     169        // Verify directory is writable
     170        // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_is_writable -- Simple permission check before file operations
     171        if (!is_writable($family_dir)) {
     172            return new \WP_Error('dir_not_writable', __('Font directory is not writable. Check file permissions.', 'safefonts'));
    147173        }
    148174
     
    155181
    156182        // Copy file to assets directory
    157         if (!copy($font_file_path, $destination)) {
    158             return new \WP_Error('copy_failed', __('Failed to copy font file.', 'safefonts'));
    159         }
     183        // Use @ to suppress PHP warnings and check result properly
     184        $copy_result = @copy($font_file_path, $destination);
     185
     186        if (!$copy_result) {
     187            $error_msg = error_get_last();
     188            return new \WP_Error('copy_failed', __('Failed to copy font file.', 'safefonts') . ' ' . ($error_msg ? $error_msg['message'] : ''));
     189        }
     190
     191        // Verify file was actually copied
     192        if (!file_exists($destination)) {
     193            return new \WP_Error('file_not_copied', __('Font file was not copied to destination.', 'safefonts'));
     194        }
     195
     196        // Set proper file permissions
     197        // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_chmod -- Setting secure file permissions for uploaded font
     198        chmod($destination, 0644);
    160199
    161200        // Save to database
     
    320359
    321360    /**
     361     * Get appropriate fallback fonts based on font family name
     362     *
     363     * @param string $family_name Font family name
     364     * @return string Fallback font stack
     365     */
     366    private function get_font_fallback($family_name) {
     367        $family_lower = strtolower($family_name);
     368
     369        // Monospace fonts
     370        if (strpos($family_lower, 'mono') !== false ||
     371            strpos($family_lower, 'code') !== false ||
     372            strpos($family_lower, 'courier') !== false ||
     373            strpos($family_lower, 'console') !== false) {
     374            return ', monospace';
     375        }
     376
     377        // Serif fonts
     378        if (strpos($family_lower, 'serif') !== false ||
     379            strpos($family_lower, 'times') !== false ||
     380            strpos($family_lower, 'garamond') !== false ||
     381            strpos($family_lower, 'baskerville') !== false ||
     382            strpos($family_lower, 'caslon') !== false) {
     383            return ', serif';
     384        }
     385
     386        // Cursive/handwriting fonts
     387        if (strpos($family_lower, 'script') !== false ||
     388            strpos($family_lower, 'cursive') !== false ||
     389            strpos($family_lower, 'handwriting') !== false ||
     390            strpos($family_lower, 'brush') !== false) {
     391            return ', cursive, sans-serif';
     392        }
     393
     394        // Default to sans-serif
     395        return ', sans-serif';
     396    }
     397
     398    /**
    322399     * Clear fonts cache
    323400     */
  • safefonts/tags/1.1.2/readme.txt

    r3388520 r3388720  
    44Requires at least: 5.0
    55Tested up to: 6.8
    6 Stable tag: 1.1.1
     6Stable tag: 1.1.2
    77Requires PHP: 7.4
    88License: GPLv2 or later
     
    193193
    194194== Changelog ==
     195
     196= 1.1.2 =
     197* Fix: Fonts now display correctly in Gutenberg block editor
     198* NEW: Generate .has-{slug}-font-family CSS classes for Gutenberg typography controls
     199* NEW: Intelligent font fallback detection (serif, sans-serif, monospace, cursive)
     200* Fix: Database migration now properly adds family_slug column for users upgrading from v1.0.x
     201* Improved: Enhanced error handling for font uploads with detailed error messages
     202* Improved: Better directory writability checks before file operations
     203* Technical: Added PHPCS ignore comments for legitimate direct filesystem operations
    195204
    196205= 1.1.1 =
  • safefonts/tags/1.1.2/safefonts.php

    r3388505 r3388720  
    44 * Plugin URI: https://safefonts.com
    55 * Description: Secure font management for WordPress with Gutenberg integration and local hosting for GDPR compliance.
    6  * Version: 1.1.1
     6 * Version: 1.1.2
    77 * Requires at least: 5.0
    88 * Requires PHP: 7.4
     
    2121
    2222// Define plugin constants
    23 define('SAFEFONTS_VERSION', '1.1.1');
     23define('SAFEFONTS_VERSION', '1.1.2');
    2424define('SAFEFONTS_PLUGIN_FILE', __FILE__);
    2525define('SAFEFONTS_PLUGIN_DIR', plugin_dir_path(__FILE__));
  • safefonts/trunk/includes/Core.php

    r3388505 r3388720  
    350350        require_once ABSPATH . 'wp-admin/includes/upgrade.php';
    351351        dbDelta($sql);
     352
     353        // Migration check: Add family_slug column if it doesn't exist (v1.1.0+)
     354        $columns = $wpdb->get_col("DESCRIBE {$table_name}"); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Migration check, runs once on activation
     355        if (!in_array('family_slug', $columns, true)) {
     356            $wpdb->query("ALTER TABLE {$table_name} ADD COLUMN family_slug varchar(255) NOT NULL DEFAULT '' AFTER font_family"); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Adding missing column for migration
     357            $wpdb->query("ALTER TABLE {$table_name} ADD KEY family_slug (family_slug)"); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Adding index for new column
     358        }
    352359
    353360        // Always check for fonts needing migration (v1.1.0+)
  • safefonts/trunk/includes/FontManager.php

    r3388505 r3388720  
    101101        $css = "/* SafeFonts - Generated CSS */\n";
    102102        $css .= "/* Generated: " . current_time('mysql') . " */\n\n";
     103        $css .= "/* ================================= */\n";
     104        $css .= "/*   FONT FACE DECLARATIONS         */\n";
     105        $css .= "/* ================================= */\n\n";
    103106
    104107        foreach ($fonts as $font) {
     
    116119        }
    117120
     121        // Generate Gutenberg CSS classes
     122        $css .= "/* ================================= */\n";
     123        $css .= "/*   GUTENBERG FONT FAMILY CLASSES  */\n";
     124        $css .= "/* ================================= */\n\n";
     125
     126        $fonts_by_family = $this->get_fonts_by_family();
     127        foreach ($fonts_by_family as $family => $variants) {
     128            $slug = sanitize_title($family);
     129            $fallback = $this->get_font_fallback($family);
     130
     131            $css .= ".has-" . $slug . "-font-family {\n";
     132            $css .= "  font-family: '" . esc_attr($family) . "'" . $fallback . ";\n";
     133            $css .= "}\n\n";
     134        }
     135
    118136        return $css;
    119137    }
     
    144162        $family_dir = SAFEFONTS_ASSETS_DIR . $family_slug . '/';
    145163        if (!file_exists($family_dir)) {
    146             wp_mkdir_p($family_dir);
     164            if (!wp_mkdir_p($family_dir)) {
     165                return new \WP_Error('mkdir_failed', __('Failed to create font family directory.', 'safefonts'));
     166            }
     167        }
     168
     169        // Verify directory is writable
     170        // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_is_writable -- Simple permission check before file operations
     171        if (!is_writable($family_dir)) {
     172            return new \WP_Error('dir_not_writable', __('Font directory is not writable. Check file permissions.', 'safefonts'));
    147173        }
    148174
     
    155181
    156182        // Copy file to assets directory
    157         if (!copy($font_file_path, $destination)) {
    158             return new \WP_Error('copy_failed', __('Failed to copy font file.', 'safefonts'));
    159         }
     183        // Use @ to suppress PHP warnings and check result properly
     184        $copy_result = @copy($font_file_path, $destination);
     185
     186        if (!$copy_result) {
     187            $error_msg = error_get_last();
     188            return new \WP_Error('copy_failed', __('Failed to copy font file.', 'safefonts') . ' ' . ($error_msg ? $error_msg['message'] : ''));
     189        }
     190
     191        // Verify file was actually copied
     192        if (!file_exists($destination)) {
     193            return new \WP_Error('file_not_copied', __('Font file was not copied to destination.', 'safefonts'));
     194        }
     195
     196        // Set proper file permissions
     197        // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_chmod -- Setting secure file permissions for uploaded font
     198        chmod($destination, 0644);
    160199
    161200        // Save to database
     
    320359
    321360    /**
     361     * Get appropriate fallback fonts based on font family name
     362     *
     363     * @param string $family_name Font family name
     364     * @return string Fallback font stack
     365     */
     366    private function get_font_fallback($family_name) {
     367        $family_lower = strtolower($family_name);
     368
     369        // Monospace fonts
     370        if (strpos($family_lower, 'mono') !== false ||
     371            strpos($family_lower, 'code') !== false ||
     372            strpos($family_lower, 'courier') !== false ||
     373            strpos($family_lower, 'console') !== false) {
     374            return ', monospace';
     375        }
     376
     377        // Serif fonts
     378        if (strpos($family_lower, 'serif') !== false ||
     379            strpos($family_lower, 'times') !== false ||
     380            strpos($family_lower, 'garamond') !== false ||
     381            strpos($family_lower, 'baskerville') !== false ||
     382            strpos($family_lower, 'caslon') !== false) {
     383            return ', serif';
     384        }
     385
     386        // Cursive/handwriting fonts
     387        if (strpos($family_lower, 'script') !== false ||
     388            strpos($family_lower, 'cursive') !== false ||
     389            strpos($family_lower, 'handwriting') !== false ||
     390            strpos($family_lower, 'brush') !== false) {
     391            return ', cursive, sans-serif';
     392        }
     393
     394        // Default to sans-serif
     395        return ', sans-serif';
     396    }
     397
     398    /**
    322399     * Clear fonts cache
    323400     */
  • safefonts/trunk/readme.txt

    r3388520 r3388720  
    44Requires at least: 5.0
    55Tested up to: 6.8
    6 Stable tag: 1.1.1
     6Stable tag: 1.1.2
    77Requires PHP: 7.4
    88License: GPLv2 or later
     
    193193
    194194== Changelog ==
     195
     196= 1.1.2 =
     197* Fix: Fonts now display correctly in Gutenberg block editor
     198* NEW: Generate .has-{slug}-font-family CSS classes for Gutenberg typography controls
     199* NEW: Intelligent font fallback detection (serif, sans-serif, monospace, cursive)
     200* Fix: Database migration now properly adds family_slug column for users upgrading from v1.0.x
     201* Improved: Enhanced error handling for font uploads with detailed error messages
     202* Improved: Better directory writability checks before file operations
     203* Technical: Added PHPCS ignore comments for legitimate direct filesystem operations
    195204
    196205= 1.1.1 =
  • safefonts/trunk/safefonts.php

    r3388505 r3388720  
    44 * Plugin URI: https://safefonts.com
    55 * Description: Secure font management for WordPress with Gutenberg integration and local hosting for GDPR compliance.
    6  * Version: 1.1.1
     6 * Version: 1.1.2
    77 * Requires at least: 5.0
    88 * Requires PHP: 7.4
     
    2121
    2222// Define plugin constants
    23 define('SAFEFONTS_VERSION', '1.1.1');
     23define('SAFEFONTS_VERSION', '1.1.2');
    2424define('SAFEFONTS_PLUGIN_FILE', __FILE__);
    2525define('SAFEFONTS_PLUGIN_DIR', plugin_dir_path(__FILE__));
Note: See TracChangeset for help on using the changeset viewer.