Plugin Directory

Changeset 3467951


Ignore:
Timestamp:
02/23/2026 06:53:38 PM (6 weeks ago)
Author:
DaanvandenBergh
Message:

Update to version 6.1.4 from GitHub

Location:
host-webfonts-local
Files:
8 edited
1 copied

Legend:

Unmodified
Added
Removed
  • host-webfonts-local/tags/6.1.4/host-webfonts-local.php

    r3465921 r3467951  
    44 * Plugin URI: https://daan.dev/wordpress/omgf/
    55 * Description: Increase GDPR/DSGVO compliance and leverage browser cache by automatically self-hosting Google Fonts.
    6  * Version: 6.1.3
     6 * Version: 6.1.4
    77 * Author: Daan from Daan.dev
    88 * Author URI: https://daan.dev
  • host-webfonts-local/tags/6.1.4/readme.txt

    r3465921 r3467951  
    44Requires at least: 5.9
    55Tested up to: 6.9
    6 Stable tag: 6.1.3
     6Stable tag: 6.1.4
    77Requires PHP: 7.3
    88License: GPLv2 or later
     
    8989== Changelog ==
    9090
     91= 6.1.4 =
     92* Improved: options are now retrieved much more efficiently.
     93* Improved: minor security fixes.
     94* Deprecated: omgf_frontend_preloaded_fonts and omgf_frontend_optimized_fonts are deprecated and will be removed in a future release.
     95              They are replaced by omgf_filter_preloaded_fonts and omgf_filter_optimized_fonts.
     96
    9197= 6.1.3 =
    9298* Coincidentally found a bug that has been haunting me for years, that's why I'm releasing this quick patch release.
  • host-webfonts-local/tags/6.1.4/src/Frontend/Process.php

    r3447167 r3467951  
    3434    ];
    3535
    36     const RESOURCE_HINTS_URLS  = [
     36    const RESOURCE_HINTS_URLS = [
    3737        'fonts.googleapis.com',
    3838        'fonts.gstatic.com',
     
    4141    ];
    4242
    43     const RESOURCE_HINTS_ATTR  = [ 'dns-prefetch', 'preconnect', 'preload' ];
     43    const RESOURCE_HINTS_ATTR = [ 'dns-prefetch', 'preconnect', 'preload' ];
    4444
    4545    /**
     
    112112     * Generates a timestamp and stores it to the DB, which is appended to the stylesheet and fonts URLs.
    113113     *
     114     * @return int
     115     *
     116     * @codeCoverageIgnore
     117     * @see self::build_search_replace()
     118     *
    114119     * @see StylesheetGenerator::build_source_string()
    115      * @see self::build_search_replace()
    116      *
    117      * @return int
    118      *
    119      * @codeCoverageIgnore
    120120     */
    121121    private function generate_timestamp() {
     
    143143
    144144        if ( $this->break ||
    145             isset( $_GET[ 'nomgf' ] ) ||
    146             ( ( $test_mode_enabled && ! current_user_can( 'manage_options' ) && ! isset( $_GET[ 'omgf_optimize' ] ) ) && ( ! current_user_can( 'manage_options' ) && ! isset( $_GET[ 'omgf' ] ) ) ) ) {
     145             isset( $_GET['nomgf'] ) ||
     146             ( ( $test_mode_enabled && ! current_user_can( 'manage_options' ) && ! isset( $_GET['omgf_optimize'] ) ) && ( ! current_user_can( 'manage_options' ) && ! isset( $_GET['omgf'] ) ) ) ) {
    147147            return;
    148148        }
     
    171171     */
    172172    public function add_preloads() {
    173         $preloaded_fonts = apply_filters( 'omgf_frontend_preloaded_fonts', OMGF::preloaded_fonts() );
     173        $preloaded_fonts = OMGF::preloaded_fonts();
    174174
    175175        if ( ! $preloaded_fonts ) {
     
    177177        }
    178178
    179         $optimized_fonts = apply_filters( 'omgf_frontend_optimized_fonts', OMGF::optimized_fonts() );
     179        $optimized_fonts = OMGF::optimized_fonts();
    180180        $i               = 0;
    181181
     
    210210                    $url_parts = parse_url( $url );
    211211
    212                     if ( ! empty( $url_parts[ 'host' ] ) && ! empty( $url_parts[ 'path' ] ) ) {
    213                         $url = '//' . $url_parts[ 'host' ] . $url_parts[ 'path' ]; // @codeCoverageIgnore
     212                    if ( ! empty( $url_parts['host'] ) && ! empty( $url_parts['path'] ) ) {
     213                        $url = '//' . $url_parts['host'] . $url_parts['path']; // @codeCoverageIgnore
    214214                    } else {
    215215                        $url = str_replace( [ 'http:', 'https:' ], '', $url );
     
    300300         */
    301301        if ( self::query_param_exists( 'action' ) ) {
    302             if ( in_array( $_GET[ 'action' ], self::$edit_actions, true ) ) {
     302            if ( in_array( $_GET['action'], self::$edit_actions, true ) ) {
    303303                return false;
    304304            }
     
    310310         * @see https://www.modpagespeed.com/doc/experiment#ModPagespeed
    311311         */
    312         if ( self::query_param_exists( 'PageSpeed' ) && 'off' === $_GET[ 'PageSpeed' ] ) {
     312        if ( self::query_param_exists( 'PageSpeed' ) && 'off' === $_GET['PageSpeed'] ) {
    313313            return false;
    314314        }
     
    340340     * Returns the buffer for filtering, so page cache doesn't break.
    341341     *
     342     * @return string Valid HTML
     343     *
     344     * @codeCoverageIgnore
    342345     * @since v5.0.0 Tested with:
    343346     *               - Asset Cleanup Pro
     
    363366     * Not tested (yet):
    364367     * TODO: [OMGF-41] - Swift Performance
    365      * @return string Valid HTML
    366      *
    367      * @codeCoverageIgnore
    368368     */
    369369    public function return_buffer( $html ) {
     
    378378     * We're downloading the fonts, so preconnecting to Google is a waste of time. Literally.
    379379     *
     380     * @param string $html Valid HTML.
     381     *
     382     * @return string Valid HTML.
    380383     * @since v5.0.5 Use a regular expression to match all resource hints.
    381384     *
    382      * @param string $html Valid HTML.
    383      *
    384      * @return string Valid HTML.
    385385     */
    386386    public function remove_resource_hints( $html ) {
     
    391391        preg_match_all( '/(?=<link).+?(?<=>)/s', $html, $resource_hints );
    392392
    393         if ( empty( $resource_hints[ 0 ] ) ) {
     393        if ( empty( $resource_hints[0] ) ) {
    394394            return $html; // @codeCoverageIgnore
    395395        }
     
    402402         */
    403403        $search = array_filter(
    404             $resource_hints[ 0 ],
     404            $resource_hints[0],
    405405            function ( $resource_hint ) {
    406406                preg_match( '/href=[\'"](https?:)?\/\/(.*?)[\'"\/]/', $resource_hint, $url );
    407407                preg_match( '/rel=[\'"](.*?)[ \'"]/', $resource_hint, $attr );
    408408
    409                 if ( empty( $url[ 2 ] ) || empty( $attr[ 1 ] ) ) {
     409                if ( empty( $url[2] ) || empty( $attr[1] ) ) {
    410410                    return false; // @codeCoverageIgnore
    411411                }
    412412
    413                 $url  = $url[ 2 ];
    414                 $attr = $attr[ 1 ];
     413                $url  = $url[2];
     414                $attr = $attr[1];
    415415
    416416                return ! empty( preg_grep( "/$url/", self::RESOURCE_HINTS_URLS ) ) && in_array( $attr, self::RESOURCE_HINTS_ATTR );
     
    447447        preg_match_all( '/<link.*?[\/]?>/s', $html, $links );
    448448
    449         if ( empty( $links[ 0 ] ) ) {
     449        if ( empty( $links[0] ) ) {
    450450            return apply_filters( 'omgf_processed_html', $html, $this ); // @codeCoverageIgnore
    451451        }
     
    461461         */
    462462        $links = array_filter(
    463             $links[ 0 ],
     463            $links[0],
    464464            function ( $link ) {
    465465                return apply_filters(
     
    474474        $search_replace = $this->build_search_replace( $google_fonts );
    475475
    476         if ( empty( $search_replace[ 'search' ] ) || empty( $search_replace[ 'replace' ] ) ) {
     476        if ( empty( $search_replace['search'] ) || empty( $search_replace['replace'] ) ) {
    477477            return apply_filters( 'omgf_processed_html', $html, $this );
    478478        }
     
    484484         * @since v5.3.7
    485485         */
    486         foreach ( $search_replace[ 'search' ] as $key => $search ) {
     486        foreach ( $search_replace['search'] as $key => $search ) {
    487487            $position = strpos( $html, $search );
    488488
    489             if ( $position !== false && isset( $search_replace[ 'replace' ][ $key ] ) ) {
    490                 $html = substr_replace( $html, $search_replace[ 'replace' ][ $key ], $position, strlen( $search ) );
     489            if ( $position !== false && isset( $search_replace['replace'][ $key ] ) ) {
     490                $html = substr_replace( $html, $search_replace['replace'][ $key ], $position, strlen( $search ) );
    491491            }
    492492        }
     
    498498
    499499    /**
     500     * @return bool
    500501     * @since v5.0.5 Check if current page is AMP page.
    501      * @return bool
    502502     */
    503503    private function is_amp() {
     
    508508     * Builds a processable array of Google Fonts' ID and (external) URL.
    509509     *
    510      * @param array  $links
     510     * @param array $links
    511511     * @param string $handle If an ID attribute is not defined, this will be used instead.
    512512     *
     
    522522             * @var array $id Fallback to empty string if no id attribute exists.
    523523             */
    524             $id = $this->strip_css_tag( $id[ 'id' ] ?? '' );
     524            $id = $this->strip_css_tag( $id['id'] ?? '' );
    525525
    526526            preg_match( '/href=[\'"](?P<href>.*?)[\'"]/', $link, $href );
     
    529529             * No valid href attribute provide in link element.
    530530             */
    531             if ( ! isset( $href[ 'href' ] ) ) {
     531            if ( ! isset( $href['href'] ) ) {
    532532                continue; // @codeCoverageIgnore
    533533            }
     
    543543             */
    544544            if ( ! $id ) {
    545                 $id = "$handle-" . strlen( $href[ 'href' ] ); // @codeCoverageIgnore
    546             }
    547 
    548             $google_fonts[ $key ][ 'id' ]   = apply_filters( 'omgf_frontend_process_fonts_set', $id, $href );
    549             $google_fonts[ $key ][ 'link' ] = $link;
     545                $id = "$handle-" . strlen( $href['href'] ); // @codeCoverageIgnore
     546            }
     547
     548            $google_fonts[ $key ]['id']   = apply_filters( 'omgf_frontend_process_fonts_set', $id, $href );
     549            $google_fonts[ $key ]['link'] = $link;
    550550            /**
    551551             * This is used for search/replace later on. This shouldn't be tampered with.
    552552             */
    553             $google_fonts[ $key ][ 'href' ] = apply_filters( 'omgf_frontend_process_fonts_set_href', $href[ 'href' ], $link );
     553            $google_fonts[ $key ]['href'] = apply_filters( 'omgf_frontend_process_fonts_set_href', $href['href'], $link );
    554554        }
    555555
     
    560560     * Strip "-css" from the end of the stylesheet id, which WordPress adds to properly enqueued stylesheets.
    561561     *
     562     * @param mixed $handle
     563     *
     564     * @return mixed
    562565     * @since v5.0.1 This eases the migration from v4.6.0.
    563566     *
    564      * @param mixed $handle
    565      *
    566      * @return mixed
    567567     */
    568568    private function strip_css_tag( $handle ) {
     
    600600             * Handles should be all lowercase to prevent duplication issues on some filesystems.
    601601             */
    602             $handle          = strtolower( $stack[ 'id' ] );
     602            $handle          = strtolower( $stack['id'] );
    603603            $original_handle = $handle;
    604604
     
    611611                OMGF::unloaded_stylesheets() && in_array( $handle, OMGF::unloaded_stylesheets() )
    612612            ) ) {
    613                 $search[ $key ]  = $stack[ 'link' ]; // @codeCoverageIgnore
     613                $search[ $key ]  = $stack['link']; // @codeCoverageIgnore
    614614                $replace[ $key ] = ''; // @codeCoverageIgnore
    615615
     
    617617            }
    618618
    619             $cache_key = OMGF::get_cache_key( $stack[ 'id' ] );
     619            $cache_key = OMGF::get_cache_key( $stack['id'] );
    620620
    621621            /**
     
    629629             * Regular requests (in the frontend) will end here if the file exists.
    630630             */
    631             if ( ! isset( $_GET[ 'omgf_optimize' ] ) && file_exists( OMGF_UPLOAD_DIR . "/$handle/$handle.css" ) ) {
    632                 $search[ $key ]  = $stack[ 'href' ];
     631            if ( ! isset( $_GET['omgf_optimize'] ) && file_exists( OMGF_UPLOAD_DIR . "/$handle/$handle.css" ) ) {
     632                $search[ $key ]  = $stack['href'];
    633633                $replace[ $key ] = OMGF_UPLOAD_URL . "/$handle/$handle.css?ver=" . $this->timestamp;
    634634
     
    639639             * @since v5.3.7 decode URL and special HTML chars to make sure all params are properly processed later on.
    640640             */
    641             $href         = urldecode( htmlspecialchars_decode( $stack[ 'href' ] ) );
     641            $href         = urldecode( htmlspecialchars_decode( $stack['href'] ) );
    642642            $parsed_query = wp_parse_url( $href, PHP_URL_QUERY );
    643643            $query        = [];
     
    650650             * If required parameters aren't set, this request is most likely invalid. Let's just remove it.
    651651             */
    652             if ( apply_filters( 'omgf_frontend_process_invalid_request', ! isset( $query[ 'family' ] ), $href ) ) {
    653                 $search[ $key ]  = $stack[ 'link' ];
     652            if ( apply_filters( 'omgf_frontend_process_invalid_request', ! isset( $query['family'] ), $href ) ) {
     653                $search[ $key ]  = $stack['link'];
    654654                $replace[ $key ] = '';
    655655
     
    657657            }
    658658
    659             $optimize = new Optimize( $stack[ 'href' ], $handle, $original_handle );
     659            $optimize = new Optimize( $stack['href'], $handle, $original_handle );
    660660
    661661            /**
     
    664664            $cached_url = $optimize->process();
    665665
    666             $search[ $key ]  = $stack[ 'href' ];
     666            $search[ $key ]  = $stack['href'];
    667667            $replace[ $key ] = $cached_url ? $cached_url . '?ver=' . $this->timestamp : '';
    668668        }
     
    704704     */
    705705    public function add_success_message( $html ) {
    706         if ( ! isset( $_GET[ 'omgf_optimize' ] ) || wp_doing_ajax() || ! current_user_can( 'manage_options' ) ) {
     706        if ( ! isset( $_GET['omgf_optimize'] ) || wp_doing_ajax() || ! current_user_can( 'manage_options' ) ) {
    707707            return $html;
    708708        }
     
    710710        $parts = preg_split( '/(<body.*?>)/', $html, - 1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE );
    711711
    712         if ( empty( $parts[ 0 ] ) || empty( $parts[ 1 ] ) || empty( $parts[ 2 ] ) ) {
     712        if ( empty( $parts[0] ) || empty( $parts[1] ) || empty( $parts[2] ) ) {
    713713            return $html;
    714714        }
     
    720720        );
    721721
    722         return $parts[ 0 ] . $parts[ 1 ] . sprintf( $message_div, $message ) . $parts[ 2 ];
     722        return $parts[0] . $parts[1] . sprintf( $message_div, $message ) . $parts[2];
    723723    }
    724724}
  • host-webfonts-local/tags/6.1.4/src/Helper.php

    r3465921 r3467951  
    2222    /**
    2323     * Property to hold all settings.
    24      * @var mixed
    25      */
    26     private static $settings;
     24     * @var array
     25     */
     26    private static $settings = [];
     27
     28    /**
     29     * @var array $preloaded_fonts
     30     */
     31    private static $preloaded_fonts = [];
     32
     33    /**
     34     * @var array $unloaded_fonts
     35     */
     36    private static $unloaded_fonts = [];
     37
     38    /**
     39     * @var array $unloaded_stylesheets
     40     */
     41    private static $unloaded_stylesheets = [];
     42
     43    /**
     44     * @var array $cache_keys
     45     */
     46    private static $cache_keys = [];
     47
     48    /**
     49     * @var array $optimized_fonts
     50     */
     51    private static $optimized_fonts = [];
     52
     53    /**
     54     * @var array $admin_optimized_fonts
     55     */
     56    private static $admin_optimized_fonts = [];
     57
     58    /**
     59     * @var array $subsets
     60     */
     61    private static $subsets = [];
    2762
    2863    /**
     
    4075        // If $setting starts with 'omgf_' it should be saved in a separate row.
    4176        if ( str_starts_with( $setting, 'omgf_' ) ) {
    42             return update_option( $setting, $value, $autoload );
    43         }
    44 
    45         if ( self::$settings === null ) {
     77            $updated = update_option( $setting, $value, $autoload );
     78
     79            if ( $updated ) {
     80                self::reset_cache();
     81            }
     82
     83            return $updated;
     84        }
     85
     86        if ( empty( self::$settings ) ) {
    4687            self::$settings = self::get_settings(); // @codeCoverageIgnore
    4788        }
     
    4990        self::$settings[ $setting ] = $value;
    5091
    51         return update_option( 'omgf_settings', self::$settings );
     92        $updated = update_option( 'omgf_settings', self::$settings );
     93
     94        if ( $updated ) {
     95            self::reset_cache();
     96        }
     97
     98        return $updated;
     99    }
     100
     101    /**
     102     * Resets all static caches.
     103     *
     104     * @return void
     105     */
     106    public static function reset_cache() {
     107        self::$settings              = [];
     108        self::$preloaded_fonts       = [];
     109        self::$unloaded_fonts        = [];
     110        self::$unloaded_stylesheets  = [];
     111        self::$cache_keys            = [];
     112        self::$admin_optimized_fonts = [];
     113        self::$optimized_fonts       = [];
     114        self::$subsets               = [];
    52115    }
    53116
     
    62125            'omgf_settings_defaults',
    63126            [
    64                 Settings::OMGF_OPTIMIZE_SETTING_DISPLAY_OPTION    => 'swap',
    65                 Settings::OMGF_OPTIMIZE_SETTING_TEST_MODE         => '',
    66                 Settings::OMGF_ADV_SETTING_LEGACY_MODE            => '',
    67                 Settings::OMGF_ADV_SETTING_COMPATIBILITY          => '',
    68                 Settings::OMGF_ADV_SETTING_AUTO_SUBSETS           => 'on',
    69                 Settings::OMGF_ADV_SETTING_SUBSETS                => [ 'latin', 'latin-ext' ],
    70                 Settings::OMGF_ADV_SETTING_DISABLE_ADMIN_BAR_MENU => '',
    71                 Settings::OMGF_ADV_SETTING_DEBUG_MODE             => '',
    72                 Settings::OMGF_ADV_SETTING_UNINSTALL              => '',
     127                Settings::OMGF_OPTIMIZE_SETTING_DISPLAY_OPTION     => 'swap',
     128                Settings::OMGF_OPTIMIZE_SETTING_TEST_MODE          => '',
     129                Settings::OMGF_OPTIMIZE_SETTING_UNLOAD_STYLESHEETS => '',
     130                Settings::OMGF_OPTIMIZE_SETTING_CACHE_KEYS         => '',
     131                Settings::OMGF_ADV_SETTING_LEGACY_MODE             => '',
     132                Settings::OMGF_ADV_SETTING_COMPATIBILITY           => '',
     133                Settings::OMGF_ADV_SETTING_AUTO_SUBSETS            => 'on',
     134                Settings::OMGF_ADV_SETTING_SUBSETS                 => [ 'latin', 'latin-ext' ],
     135                Settings::OMGF_ADV_SETTING_DISABLE_ADMIN_BAR_MENU  => '',
     136                Settings::OMGF_ADV_SETTING_DEBUG_MODE              => '',
     137                Settings::OMGF_ADV_SETTING_UNINSTALL               => '',
    73138            ]
    74139        );
     
    93158    public static function delete_option( $setting ) {
    94159        if ( str_starts_with( $setting, 'omgf_' ) || apply_filters( 'omgf_delete_option', false, $setting ) ) {
    95             return delete_option( $setting );
     160            $deleted = delete_option( $setting );
     161
     162            if ( $deleted ) {
     163                self::reset_cache();
     164            }
     165
     166            return $deleted;
    96167        }
    97168
     
    103174        unset( self::$settings[ $setting ] );
    104175
    105         return update_option( 'omgf_settings', self::$settings );
     176        $deleted = update_option( 'omgf_settings', self::$settings );
     177
     178        if ( $deleted ) {
     179            self::reset_cache();
     180        }
     181
     182        return $deleted;
    106183    }
    107184
     
    112189     */
    113190    public static function preloaded_fonts() {
    114         static $preloaded_fonts = [];
    115 
    116         if ( empty( $preloaded_fonts ) ) {
    117             $preloaded_fonts = self::get_option( Settings::OMGF_OPTIMIZE_SETTING_PRELOAD_FONTS, [] );
    118         }
    119 
    120         return $preloaded_fonts;
     191        if ( empty( self::$preloaded_fonts ) ) {
     192            self::$preloaded_fonts = self::get_option( Settings::OMGF_OPTIMIZE_SETTING_PRELOAD_FONTS, [] );
     193        }
     194
     195        self::$preloaded_fonts = apply_filters( 'omgf_filter_preloaded_fonts', self::$preloaded_fonts );
     196
     197        /**
     198         * Just to make sure that everything keeps working.
     199         */
     200        if ( has_filter( 'omgf_frontend_preloaded_fonts' ) ) {
     201            _deprecated_hook( 'omgf_frontend_preloaded_fonts', '6.1.4', 'omgf_filter_preloaded_fonts' );
     202
     203            self::$preloaded_fonts = apply_filters( 'omgf_frontend_preloaded_fonts', self::$preloaded_fonts );
     204        }
     205
     206        return self::$preloaded_fonts;
    121207    }
    122208
     
    139225            $name  = str_replace( 'omgf_', '', $name );
    140226
     227            // get_option() should take care of this, but sometimes it doesn't.
     228            if ( is_string( $value ) ) {
     229                $value = maybe_unserialize( $value );
     230            }
     231
    141232            return apply_filters( "omgf_setting_$name", $value );
    142233        }
     
    161252     */
    162253    public static function unloaded_fonts() {
    163         static $unloaded_fonts = [];
    164 
    165         if ( empty( $unloaded_fonts ) ) {
    166             $unloaded_fonts = self::get_option( Settings::OMGF_OPTIMIZE_SETTING_UNLOAD_FONTS, [] );
    167         }
    168 
    169         return $unloaded_fonts;
     254        if ( empty( self::$unloaded_fonts ) ) {
     255            self::$unloaded_fonts = self::get_option( Settings::OMGF_OPTIMIZE_SETTING_UNLOAD_FONTS, [] );
     256        }
     257
     258        return apply_filters( 'omgf_filter_unloaded_fonts', self::$unloaded_fonts );
    170259    }
    171260
     
    176265     */
    177266    public static function unloaded_stylesheets() {
    178         static $unloaded_stylesheets = [];
    179 
    180         if ( empty( $unloaded_stylesheets ) ) {
     267        if ( empty( self::$unloaded_stylesheets ) ) {
    181268            // Returns a string with one empty element if the option is empty, that's why we array_filter it.
    182             $unloaded_stylesheets = explode( ',', self::get_option( Settings::OMGF_OPTIMIZE_SETTING_UNLOAD_STYLESHEETS, '' ) );
    183         }
    184 
    185         // Remove empty elements (and store it to the static variable before returning it)
    186         $unloaded_stylesheets = array_filter( $unloaded_stylesheets );
    187 
    188         return $unloaded_stylesheets;
     269            self::$unloaded_stylesheets = array_filter( explode( ',', self::get_option( Settings::OMGF_OPTIMIZE_SETTING_UNLOAD_STYLESHEETS, '' ) ) );
     270        }
     271
     272        return apply_filters( 'omgf_filter_unloaded_stylesheets', self::$unloaded_stylesheets );
    189273    }
    190274
     
    217301     */
    218302    public static function cache_keys() {
    219         static $cache_keys = [];
    220 
    221         if ( empty( $cache_keys ) ) {
    222             $cache_keys = explode( ',', self::get_option( Settings::OMGF_OPTIMIZE_SETTING_CACHE_KEYS, '' ) );
    223         }
    224 
    225         // Remove empty elements.
    226         $cache_keys = array_filter( $cache_keys );
     303        if ( empty( self::$cache_keys ) ) {
     304            // Returns a string with one empty element if the option is empty, that's why we array_filter it.
     305            self::$cache_keys = array_filter( explode( ',', self::get_option( Settings::OMGF_OPTIMIZE_SETTING_CACHE_KEYS, '' ) ) );
     306        }
    227307
    228308        /**
     
    230310         * the (default) stylesheet handles from the optimized fonts option.
    231311         */
    232         if ( empty( $cache_keys ) ) {
     312        if ( empty( self::$cache_keys ) ) {
    233313            $optimized_fonts = self::admin_optimized_fonts(); // @codeCoverageIgnore
    234314
    235             $cache_keys = array_keys( $optimized_fonts ); //@codeCoverageIgnore
    236         }
    237 
    238         return $cache_keys;
     315            self::$cache_keys = array_keys( $optimized_fonts ); //@codeCoverageIgnore
     316        }
     317
     318        return self::$cache_keys;
    239319    }
    240320
    241321    /**
    242322     * Optimized Local Fonts to be displayed in the Optimize Local Fonts table.
     323     *
    243324     * Use a static variable to reduce database reads/writes.
    244325     *
     
    253334     */
    254335    public static function admin_optimized_fonts( $maybe_add = [], $force_add = false ) {
    255         static $optimized_fonts = [];
    256 
    257         /**
    258          * Get a fresh copy from the database if $optimized_fonts is empty|null|false (on 1st run)
    259          */
    260         if ( empty( $optimized_fonts ) ) {
    261             $optimized_fonts = self::get_option( Settings::OMGF_OPTIMIZE_SETTING_OPTIMIZED_FONTS, [] );
     336        /**
     337         * Get a fresh copy from the database if self::$optimized_fonts is empty|null|false (on 1st run)
     338         */
     339        if ( empty( self::$admin_optimized_fonts ) ) {
     340            self::$admin_optimized_fonts = self::get_option( Settings::OMGF_OPTIMIZE_SETTING_OPTIMIZED_FONTS, [] );
    262341        }
    263342
     
    266345         * @since v4.5.6
    267346         */
    268         if ( is_string( $optimized_fonts ) && $optimized_fonts !== '' ) {
    269             $optimized_fonts = unserialize( $optimized_fonts ); // @codeCoverageIgnore
     347        if ( is_string( self::$admin_optimized_fonts ) && self::$admin_optimized_fonts !== '' ) {
     348            self::$admin_optimized_fonts = maybe_unserialize( self::$admin_optimized_fonts ); // @codeCoverageIgnore
    270349        }
    271350
     
    274353         * @since v4.5.7
    275354         */
    276         if ( ! empty( $maybe_add ) && ( ! isset( $optimized_fonts[ key( $maybe_add ) ] ) || $force_add ) ) {
    277             $optimized_fonts = array_merge( $optimized_fonts, $maybe_add );
    278         }
    279 
    280         return $optimized_fonts ?: [];
    281     }
    282 
    283     /**
    284      * Optimized Local Fonts to be used in the frontend. Doesn\'t contain unloaded fonts.
     355        if ( ! empty( $maybe_add ) && ( ! isset( self::$admin_optimized_fonts[ key( $maybe_add ) ] ) || $force_add ) ) {
     356            self::$admin_optimized_fonts = array_merge( self::$admin_optimized_fonts, $maybe_add );
     357        }
     358
     359        return apply_filters( 'omgf_filter_admin_optimized_fonts', self::$admin_optimized_fonts ?: [] );
     360    }
     361
     362    /**
     363     * Optimized Local Fonts to be used in the frontend. Doesn't contain unloaded fonts.
    285364     * Use a static variable to reduce database reads/writes.
    286365     *
     
    292371     * @codeCoverageIgnore
    293372     * @since v5.8.1
    294      *
    295373     */
    296374    public static function optimized_fonts( $maybe_add = [], $force_add = false ) {
    297         static $optimized_fonts = [];
    298 
    299         /**
    300          * Get a fresh copy from the database if $optimized_fonts is empty|null|false (on 1st run)
    301          */
    302         if ( empty( $optimized_fonts ) ) {
    303             $optimized_fonts = self::get_option( Settings::OMGF_OPTIMIZE_SETTING_OPTIMIZED_FONTS_FRONTEND, [] );
    304         }
    305 
    306         /**
    307          * Fallback to original Optimized Fonts table.
    308          */
    309         if ( empty( $optimized_fonts ) ) {
    310             $optimized_fonts = self::admin_optimized_fonts();
     375        /**
     376         * Get a fresh copy from the database if self::$optimized_fonts is empty|null|false (on 1st run)
     377         */
     378        if ( empty( self::$optimized_fonts ) ) {
     379            self::$optimized_fonts = self::get_option( Settings::OMGF_OPTIMIZE_SETTING_OPTIMIZED_FONTS_FRONTEND, [] );
     380        }
     381
     382        /**
     383         * Fallback to the original Optimized Fonts table.
     384         */
     385        if ( empty( self::$optimized_fonts ) ) {
     386            self::$optimized_fonts = self::admin_optimized_fonts();
    311387        }
    312388
     
    315391         * @since v4.5.6
    316392         */
    317         if ( is_string( $optimized_fonts ) && $optimized_fonts !== '' ) {
    318             $optimized_fonts = unserialize( $optimized_fonts ); // @codeCoverageIgnore
     393        if ( is_string( self::$optimized_fonts ) && self::$optimized_fonts !== '' ) {
     394            self::$optimized_fonts = maybe_unserialize( self::$optimized_fonts ); // @codeCoverageIgnore
    319395        }
    320396
     
    323399         * @since v4.5.7
    324400         */
    325         if ( ! empty( $maybe_add ) && ( ! isset( $optimized_fonts[ key( $maybe_add ) ] ) || $force_add ) ) {
    326             $optimized_fonts = array_merge( $optimized_fonts, $maybe_add );
    327         }
    328 
    329         return $optimized_fonts ?: [];
     401        if ( ! empty( $maybe_add ) && ( ! isset( self::$optimized_fonts[ key( $maybe_add ) ] ) || $force_add ) ) {
     402            self::$optimized_fonts = array_merge( self::$optimized_fonts, $maybe_add );
     403        }
     404
     405        self::$optimized_fonts = apply_filters( 'omgf_filter_optimized_fonts', self::$optimized_fonts ?: [] );
     406
     407        /**
     408         * Just to make sure that everything keeps working.
     409         */
     410        if ( has_filter( 'omgf_frontend_optimized_fonts' ) ) {
     411            _deprecated_hook( 'omgf_frontend_optimized_fonts', '6.1.4', 'omgf_filter_optimized_fonts' );
     412
     413            self::$optimized_fonts = apply_filters( 'omgf_frontend_optimized_fonts', self::$optimized_fonts );
     414        }
     415
     416        return self::$optimized_fonts;
    330417    }
    331418
     
    338425     */
    339426    public static function available_used_subsets( $maybe_add = [], $intersect = false ) {
    340         static $subsets = [];
    341 
    342         if ( empty( $subsets ) ) {
    343             $subsets = self::get_option( Settings::OMGF_AVAILABLE_USED_SUBSETS, [] );
     427        if ( empty( self::$subsets ) ) {
     428            self::$subsets = self::get_option( Settings::OMGF_AVAILABLE_USED_SUBSETS, [] );
    344429        }
    345430
     
    347432         * get_option() should take care of this, but sometimes it doesn't.
    348433         */
    349         if ( is_string( $subsets ) ) {
    350             $subsets = unserialize( $subsets ); // @codeCoverageIgnore
     434        if ( is_string( self::$subsets ) ) {
     435            self::$subsets = maybe_unserialize( self::$subsets ); // @codeCoverageIgnore
    351436        }
    352437
     
    354439         * If $maybe_add doesn't exist in the cache layer yet, add it.
    355440         */
    356         if ( ! empty( $maybe_add ) && ( ! isset( $subsets[ key( $maybe_add ) ] ) ) ) {
    357             $subsets = array_merge( $subsets, $maybe_add );
     441        if ( ! empty( $maybe_add ) && ( ! isset( self::$subsets[ key( $maybe_add ) ] ) ) ) {
     442            self::$subsets = array_merge( self::$subsets, $maybe_add );
    358443        }
    359444
     
    367452             *                              { 'Lato' => { 'latin', 'latin-ext' } }
    368453             */
    369             $filtered_subsets = apply_filters( 'omgf_available_filtered_subsets', array_values( array_filter( $subsets ) ) );
     454            $filtered_subsets = apply_filters( 'omgf_available_filtered_subsets', array_values( array_filter( self::$subsets ) ) );
    370455
    371456            self::debug_array( __( 'Filtered Subsets', 'host-webfonts-local' ), $filtered_subsets );
     
    382467        }
    383468
    384         return apply_filters( 'omgf_available_subsets', $subsets );
     469        return apply_filters( 'omgf_available_subsets', self::$subsets );
    385470    }
    386471
  • host-webfonts-local/trunk/host-webfonts-local.php

    r3465921 r3467951  
    44 * Plugin URI: https://daan.dev/wordpress/omgf/
    55 * Description: Increase GDPR/DSGVO compliance and leverage browser cache by automatically self-hosting Google Fonts.
    6  * Version: 6.1.3
     6 * Version: 6.1.4
    77 * Author: Daan from Daan.dev
    88 * Author URI: https://daan.dev
  • host-webfonts-local/trunk/readme.txt

    r3465921 r3467951  
    44Requires at least: 5.9
    55Tested up to: 6.9
    6 Stable tag: 6.1.3
     6Stable tag: 6.1.4
    77Requires PHP: 7.3
    88License: GPLv2 or later
     
    8989== Changelog ==
    9090
     91= 6.1.4 =
     92* Improved: options are now retrieved much more efficiently.
     93* Improved: minor security fixes.
     94* Deprecated: omgf_frontend_preloaded_fonts and omgf_frontend_optimized_fonts are deprecated and will be removed in a future release.
     95              They are replaced by omgf_filter_preloaded_fonts and omgf_filter_optimized_fonts.
     96
    9197= 6.1.3 =
    9298* Coincidentally found a bug that has been haunting me for years, that's why I'm releasing this quick patch release.
  • host-webfonts-local/trunk/src/Frontend/Process.php

    r3447167 r3467951  
    3434    ];
    3535
    36     const RESOURCE_HINTS_URLS  = [
     36    const RESOURCE_HINTS_URLS = [
    3737        'fonts.googleapis.com',
    3838        'fonts.gstatic.com',
     
    4141    ];
    4242
    43     const RESOURCE_HINTS_ATTR  = [ 'dns-prefetch', 'preconnect', 'preload' ];
     43    const RESOURCE_HINTS_ATTR = [ 'dns-prefetch', 'preconnect', 'preload' ];
    4444
    4545    /**
     
    112112     * Generates a timestamp and stores it to the DB, which is appended to the stylesheet and fonts URLs.
    113113     *
     114     * @return int
     115     *
     116     * @codeCoverageIgnore
     117     * @see self::build_search_replace()
     118     *
    114119     * @see StylesheetGenerator::build_source_string()
    115      * @see self::build_search_replace()
    116      *
    117      * @return int
    118      *
    119      * @codeCoverageIgnore
    120120     */
    121121    private function generate_timestamp() {
     
    143143
    144144        if ( $this->break ||
    145             isset( $_GET[ 'nomgf' ] ) ||
    146             ( ( $test_mode_enabled && ! current_user_can( 'manage_options' ) && ! isset( $_GET[ 'omgf_optimize' ] ) ) && ( ! current_user_can( 'manage_options' ) && ! isset( $_GET[ 'omgf' ] ) ) ) ) {
     145             isset( $_GET['nomgf'] ) ||
     146             ( ( $test_mode_enabled && ! current_user_can( 'manage_options' ) && ! isset( $_GET['omgf_optimize'] ) ) && ( ! current_user_can( 'manage_options' ) && ! isset( $_GET['omgf'] ) ) ) ) {
    147147            return;
    148148        }
     
    171171     */
    172172    public function add_preloads() {
    173         $preloaded_fonts = apply_filters( 'omgf_frontend_preloaded_fonts', OMGF::preloaded_fonts() );
     173        $preloaded_fonts = OMGF::preloaded_fonts();
    174174
    175175        if ( ! $preloaded_fonts ) {
     
    177177        }
    178178
    179         $optimized_fonts = apply_filters( 'omgf_frontend_optimized_fonts', OMGF::optimized_fonts() );
     179        $optimized_fonts = OMGF::optimized_fonts();
    180180        $i               = 0;
    181181
     
    210210                    $url_parts = parse_url( $url );
    211211
    212                     if ( ! empty( $url_parts[ 'host' ] ) && ! empty( $url_parts[ 'path' ] ) ) {
    213                         $url = '//' . $url_parts[ 'host' ] . $url_parts[ 'path' ]; // @codeCoverageIgnore
     212                    if ( ! empty( $url_parts['host'] ) && ! empty( $url_parts['path'] ) ) {
     213                        $url = '//' . $url_parts['host'] . $url_parts['path']; // @codeCoverageIgnore
    214214                    } else {
    215215                        $url = str_replace( [ 'http:', 'https:' ], '', $url );
     
    300300         */
    301301        if ( self::query_param_exists( 'action' ) ) {
    302             if ( in_array( $_GET[ 'action' ], self::$edit_actions, true ) ) {
     302            if ( in_array( $_GET['action'], self::$edit_actions, true ) ) {
    303303                return false;
    304304            }
     
    310310         * @see https://www.modpagespeed.com/doc/experiment#ModPagespeed
    311311         */
    312         if ( self::query_param_exists( 'PageSpeed' ) && 'off' === $_GET[ 'PageSpeed' ] ) {
     312        if ( self::query_param_exists( 'PageSpeed' ) && 'off' === $_GET['PageSpeed'] ) {
    313313            return false;
    314314        }
     
    340340     * Returns the buffer for filtering, so page cache doesn't break.
    341341     *
     342     * @return string Valid HTML
     343     *
     344     * @codeCoverageIgnore
    342345     * @since v5.0.0 Tested with:
    343346     *               - Asset Cleanup Pro
     
    363366     * Not tested (yet):
    364367     * TODO: [OMGF-41] - Swift Performance
    365      * @return string Valid HTML
    366      *
    367      * @codeCoverageIgnore
    368368     */
    369369    public function return_buffer( $html ) {
     
    378378     * We're downloading the fonts, so preconnecting to Google is a waste of time. Literally.
    379379     *
     380     * @param string $html Valid HTML.
     381     *
     382     * @return string Valid HTML.
    380383     * @since v5.0.5 Use a regular expression to match all resource hints.
    381384     *
    382      * @param string $html Valid HTML.
    383      *
    384      * @return string Valid HTML.
    385385     */
    386386    public function remove_resource_hints( $html ) {
     
    391391        preg_match_all( '/(?=<link).+?(?<=>)/s', $html, $resource_hints );
    392392
    393         if ( empty( $resource_hints[ 0 ] ) ) {
     393        if ( empty( $resource_hints[0] ) ) {
    394394            return $html; // @codeCoverageIgnore
    395395        }
     
    402402         */
    403403        $search = array_filter(
    404             $resource_hints[ 0 ],
     404            $resource_hints[0],
    405405            function ( $resource_hint ) {
    406406                preg_match( '/href=[\'"](https?:)?\/\/(.*?)[\'"\/]/', $resource_hint, $url );
    407407                preg_match( '/rel=[\'"](.*?)[ \'"]/', $resource_hint, $attr );
    408408
    409                 if ( empty( $url[ 2 ] ) || empty( $attr[ 1 ] ) ) {
     409                if ( empty( $url[2] ) || empty( $attr[1] ) ) {
    410410                    return false; // @codeCoverageIgnore
    411411                }
    412412
    413                 $url  = $url[ 2 ];
    414                 $attr = $attr[ 1 ];
     413                $url  = $url[2];
     414                $attr = $attr[1];
    415415
    416416                return ! empty( preg_grep( "/$url/", self::RESOURCE_HINTS_URLS ) ) && in_array( $attr, self::RESOURCE_HINTS_ATTR );
     
    447447        preg_match_all( '/<link.*?[\/]?>/s', $html, $links );
    448448
    449         if ( empty( $links[ 0 ] ) ) {
     449        if ( empty( $links[0] ) ) {
    450450            return apply_filters( 'omgf_processed_html', $html, $this ); // @codeCoverageIgnore
    451451        }
     
    461461         */
    462462        $links = array_filter(
    463             $links[ 0 ],
     463            $links[0],
    464464            function ( $link ) {
    465465                return apply_filters(
     
    474474        $search_replace = $this->build_search_replace( $google_fonts );
    475475
    476         if ( empty( $search_replace[ 'search' ] ) || empty( $search_replace[ 'replace' ] ) ) {
     476        if ( empty( $search_replace['search'] ) || empty( $search_replace['replace'] ) ) {
    477477            return apply_filters( 'omgf_processed_html', $html, $this );
    478478        }
     
    484484         * @since v5.3.7
    485485         */
    486         foreach ( $search_replace[ 'search' ] as $key => $search ) {
     486        foreach ( $search_replace['search'] as $key => $search ) {
    487487            $position = strpos( $html, $search );
    488488
    489             if ( $position !== false && isset( $search_replace[ 'replace' ][ $key ] ) ) {
    490                 $html = substr_replace( $html, $search_replace[ 'replace' ][ $key ], $position, strlen( $search ) );
     489            if ( $position !== false && isset( $search_replace['replace'][ $key ] ) ) {
     490                $html = substr_replace( $html, $search_replace['replace'][ $key ], $position, strlen( $search ) );
    491491            }
    492492        }
     
    498498
    499499    /**
     500     * @return bool
    500501     * @since v5.0.5 Check if current page is AMP page.
    501      * @return bool
    502502     */
    503503    private function is_amp() {
     
    508508     * Builds a processable array of Google Fonts' ID and (external) URL.
    509509     *
    510      * @param array  $links
     510     * @param array $links
    511511     * @param string $handle If an ID attribute is not defined, this will be used instead.
    512512     *
     
    522522             * @var array $id Fallback to empty string if no id attribute exists.
    523523             */
    524             $id = $this->strip_css_tag( $id[ 'id' ] ?? '' );
     524            $id = $this->strip_css_tag( $id['id'] ?? '' );
    525525
    526526            preg_match( '/href=[\'"](?P<href>.*?)[\'"]/', $link, $href );
     
    529529             * No valid href attribute provide in link element.
    530530             */
    531             if ( ! isset( $href[ 'href' ] ) ) {
     531            if ( ! isset( $href['href'] ) ) {
    532532                continue; // @codeCoverageIgnore
    533533            }
     
    543543             */
    544544            if ( ! $id ) {
    545                 $id = "$handle-" . strlen( $href[ 'href' ] ); // @codeCoverageIgnore
    546             }
    547 
    548             $google_fonts[ $key ][ 'id' ]   = apply_filters( 'omgf_frontend_process_fonts_set', $id, $href );
    549             $google_fonts[ $key ][ 'link' ] = $link;
     545                $id = "$handle-" . strlen( $href['href'] ); // @codeCoverageIgnore
     546            }
     547
     548            $google_fonts[ $key ]['id']   = apply_filters( 'omgf_frontend_process_fonts_set', $id, $href );
     549            $google_fonts[ $key ]['link'] = $link;
    550550            /**
    551551             * This is used for search/replace later on. This shouldn't be tampered with.
    552552             */
    553             $google_fonts[ $key ][ 'href' ] = apply_filters( 'omgf_frontend_process_fonts_set_href', $href[ 'href' ], $link );
     553            $google_fonts[ $key ]['href'] = apply_filters( 'omgf_frontend_process_fonts_set_href', $href['href'], $link );
    554554        }
    555555
     
    560560     * Strip "-css" from the end of the stylesheet id, which WordPress adds to properly enqueued stylesheets.
    561561     *
     562     * @param mixed $handle
     563     *
     564     * @return mixed
    562565     * @since v5.0.1 This eases the migration from v4.6.0.
    563566     *
    564      * @param mixed $handle
    565      *
    566      * @return mixed
    567567     */
    568568    private function strip_css_tag( $handle ) {
     
    600600             * Handles should be all lowercase to prevent duplication issues on some filesystems.
    601601             */
    602             $handle          = strtolower( $stack[ 'id' ] );
     602            $handle          = strtolower( $stack['id'] );
    603603            $original_handle = $handle;
    604604
     
    611611                OMGF::unloaded_stylesheets() && in_array( $handle, OMGF::unloaded_stylesheets() )
    612612            ) ) {
    613                 $search[ $key ]  = $stack[ 'link' ]; // @codeCoverageIgnore
     613                $search[ $key ]  = $stack['link']; // @codeCoverageIgnore
    614614                $replace[ $key ] = ''; // @codeCoverageIgnore
    615615
     
    617617            }
    618618
    619             $cache_key = OMGF::get_cache_key( $stack[ 'id' ] );
     619            $cache_key = OMGF::get_cache_key( $stack['id'] );
    620620
    621621            /**
     
    629629             * Regular requests (in the frontend) will end here if the file exists.
    630630             */
    631             if ( ! isset( $_GET[ 'omgf_optimize' ] ) && file_exists( OMGF_UPLOAD_DIR . "/$handle/$handle.css" ) ) {
    632                 $search[ $key ]  = $stack[ 'href' ];
     631            if ( ! isset( $_GET['omgf_optimize'] ) && file_exists( OMGF_UPLOAD_DIR . "/$handle/$handle.css" ) ) {
     632                $search[ $key ]  = $stack['href'];
    633633                $replace[ $key ] = OMGF_UPLOAD_URL . "/$handle/$handle.css?ver=" . $this->timestamp;
    634634
     
    639639             * @since v5.3.7 decode URL and special HTML chars to make sure all params are properly processed later on.
    640640             */
    641             $href         = urldecode( htmlspecialchars_decode( $stack[ 'href' ] ) );
     641            $href         = urldecode( htmlspecialchars_decode( $stack['href'] ) );
    642642            $parsed_query = wp_parse_url( $href, PHP_URL_QUERY );
    643643            $query        = [];
     
    650650             * If required parameters aren't set, this request is most likely invalid. Let's just remove it.
    651651             */
    652             if ( apply_filters( 'omgf_frontend_process_invalid_request', ! isset( $query[ 'family' ] ), $href ) ) {
    653                 $search[ $key ]  = $stack[ 'link' ];
     652            if ( apply_filters( 'omgf_frontend_process_invalid_request', ! isset( $query['family'] ), $href ) ) {
     653                $search[ $key ]  = $stack['link'];
    654654                $replace[ $key ] = '';
    655655
     
    657657            }
    658658
    659             $optimize = new Optimize( $stack[ 'href' ], $handle, $original_handle );
     659            $optimize = new Optimize( $stack['href'], $handle, $original_handle );
    660660
    661661            /**
     
    664664            $cached_url = $optimize->process();
    665665
    666             $search[ $key ]  = $stack[ 'href' ];
     666            $search[ $key ]  = $stack['href'];
    667667            $replace[ $key ] = $cached_url ? $cached_url . '?ver=' . $this->timestamp : '';
    668668        }
     
    704704     */
    705705    public function add_success_message( $html ) {
    706         if ( ! isset( $_GET[ 'omgf_optimize' ] ) || wp_doing_ajax() || ! current_user_can( 'manage_options' ) ) {
     706        if ( ! isset( $_GET['omgf_optimize'] ) || wp_doing_ajax() || ! current_user_can( 'manage_options' ) ) {
    707707            return $html;
    708708        }
     
    710710        $parts = preg_split( '/(<body.*?>)/', $html, - 1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE );
    711711
    712         if ( empty( $parts[ 0 ] ) || empty( $parts[ 1 ] ) || empty( $parts[ 2 ] ) ) {
     712        if ( empty( $parts[0] ) || empty( $parts[1] ) || empty( $parts[2] ) ) {
    713713            return $html;
    714714        }
     
    720720        );
    721721
    722         return $parts[ 0 ] . $parts[ 1 ] . sprintf( $message_div, $message ) . $parts[ 2 ];
     722        return $parts[0] . $parts[1] . sprintf( $message_div, $message ) . $parts[2];
    723723    }
    724724}
  • host-webfonts-local/trunk/src/Helper.php

    r3465921 r3467951  
    2222    /**
    2323     * Property to hold all settings.
    24      * @var mixed
    25      */
    26     private static $settings;
     24     * @var array
     25     */
     26    private static $settings = [];
     27
     28    /**
     29     * @var array $preloaded_fonts
     30     */
     31    private static $preloaded_fonts = [];
     32
     33    /**
     34     * @var array $unloaded_fonts
     35     */
     36    private static $unloaded_fonts = [];
     37
     38    /**
     39     * @var array $unloaded_stylesheets
     40     */
     41    private static $unloaded_stylesheets = [];
     42
     43    /**
     44     * @var array $cache_keys
     45     */
     46    private static $cache_keys = [];
     47
     48    /**
     49     * @var array $optimized_fonts
     50     */
     51    private static $optimized_fonts = [];
     52
     53    /**
     54     * @var array $admin_optimized_fonts
     55     */
     56    private static $admin_optimized_fonts = [];
     57
     58    /**
     59     * @var array $subsets
     60     */
     61    private static $subsets = [];
    2762
    2863    /**
     
    4075        // If $setting starts with 'omgf_' it should be saved in a separate row.
    4176        if ( str_starts_with( $setting, 'omgf_' ) ) {
    42             return update_option( $setting, $value, $autoload );
    43         }
    44 
    45         if ( self::$settings === null ) {
     77            $updated = update_option( $setting, $value, $autoload );
     78
     79            if ( $updated ) {
     80                self::reset_cache();
     81            }
     82
     83            return $updated;
     84        }
     85
     86        if ( empty( self::$settings ) ) {
    4687            self::$settings = self::get_settings(); // @codeCoverageIgnore
    4788        }
     
    4990        self::$settings[ $setting ] = $value;
    5091
    51         return update_option( 'omgf_settings', self::$settings );
     92        $updated = update_option( 'omgf_settings', self::$settings );
     93
     94        if ( $updated ) {
     95            self::reset_cache();
     96        }
     97
     98        return $updated;
     99    }
     100
     101    /**
     102     * Resets all static caches.
     103     *
     104     * @return void
     105     */
     106    public static function reset_cache() {
     107        self::$settings              = [];
     108        self::$preloaded_fonts       = [];
     109        self::$unloaded_fonts        = [];
     110        self::$unloaded_stylesheets  = [];
     111        self::$cache_keys            = [];
     112        self::$admin_optimized_fonts = [];
     113        self::$optimized_fonts       = [];
     114        self::$subsets               = [];
    52115    }
    53116
     
    62125            'omgf_settings_defaults',
    63126            [
    64                 Settings::OMGF_OPTIMIZE_SETTING_DISPLAY_OPTION    => 'swap',
    65                 Settings::OMGF_OPTIMIZE_SETTING_TEST_MODE         => '',
    66                 Settings::OMGF_ADV_SETTING_LEGACY_MODE            => '',
    67                 Settings::OMGF_ADV_SETTING_COMPATIBILITY          => '',
    68                 Settings::OMGF_ADV_SETTING_AUTO_SUBSETS           => 'on',
    69                 Settings::OMGF_ADV_SETTING_SUBSETS                => [ 'latin', 'latin-ext' ],
    70                 Settings::OMGF_ADV_SETTING_DISABLE_ADMIN_BAR_MENU => '',
    71                 Settings::OMGF_ADV_SETTING_DEBUG_MODE             => '',
    72                 Settings::OMGF_ADV_SETTING_UNINSTALL              => '',
     127                Settings::OMGF_OPTIMIZE_SETTING_DISPLAY_OPTION     => 'swap',
     128                Settings::OMGF_OPTIMIZE_SETTING_TEST_MODE          => '',
     129                Settings::OMGF_OPTIMIZE_SETTING_UNLOAD_STYLESHEETS => '',
     130                Settings::OMGF_OPTIMIZE_SETTING_CACHE_KEYS         => '',
     131                Settings::OMGF_ADV_SETTING_LEGACY_MODE             => '',
     132                Settings::OMGF_ADV_SETTING_COMPATIBILITY           => '',
     133                Settings::OMGF_ADV_SETTING_AUTO_SUBSETS            => 'on',
     134                Settings::OMGF_ADV_SETTING_SUBSETS                 => [ 'latin', 'latin-ext' ],
     135                Settings::OMGF_ADV_SETTING_DISABLE_ADMIN_BAR_MENU  => '',
     136                Settings::OMGF_ADV_SETTING_DEBUG_MODE              => '',
     137                Settings::OMGF_ADV_SETTING_UNINSTALL               => '',
    73138            ]
    74139        );
     
    93158    public static function delete_option( $setting ) {
    94159        if ( str_starts_with( $setting, 'omgf_' ) || apply_filters( 'omgf_delete_option', false, $setting ) ) {
    95             return delete_option( $setting );
     160            $deleted = delete_option( $setting );
     161
     162            if ( $deleted ) {
     163                self::reset_cache();
     164            }
     165
     166            return $deleted;
    96167        }
    97168
     
    103174        unset( self::$settings[ $setting ] );
    104175
    105         return update_option( 'omgf_settings', self::$settings );
     176        $deleted = update_option( 'omgf_settings', self::$settings );
     177
     178        if ( $deleted ) {
     179            self::reset_cache();
     180        }
     181
     182        return $deleted;
    106183    }
    107184
     
    112189     */
    113190    public static function preloaded_fonts() {
    114         static $preloaded_fonts = [];
    115 
    116         if ( empty( $preloaded_fonts ) ) {
    117             $preloaded_fonts = self::get_option( Settings::OMGF_OPTIMIZE_SETTING_PRELOAD_FONTS, [] );
    118         }
    119 
    120         return $preloaded_fonts;
     191        if ( empty( self::$preloaded_fonts ) ) {
     192            self::$preloaded_fonts = self::get_option( Settings::OMGF_OPTIMIZE_SETTING_PRELOAD_FONTS, [] );
     193        }
     194
     195        self::$preloaded_fonts = apply_filters( 'omgf_filter_preloaded_fonts', self::$preloaded_fonts );
     196
     197        /**
     198         * Just to make sure that everything keeps working.
     199         */
     200        if ( has_filter( 'omgf_frontend_preloaded_fonts' ) ) {
     201            _deprecated_hook( 'omgf_frontend_preloaded_fonts', '6.1.4', 'omgf_filter_preloaded_fonts' );
     202
     203            self::$preloaded_fonts = apply_filters( 'omgf_frontend_preloaded_fonts', self::$preloaded_fonts );
     204        }
     205
     206        return self::$preloaded_fonts;
    121207    }
    122208
     
    139225            $name  = str_replace( 'omgf_', '', $name );
    140226
     227            // get_option() should take care of this, but sometimes it doesn't.
     228            if ( is_string( $value ) ) {
     229                $value = maybe_unserialize( $value );
     230            }
     231
    141232            return apply_filters( "omgf_setting_$name", $value );
    142233        }
     
    161252     */
    162253    public static function unloaded_fonts() {
    163         static $unloaded_fonts = [];
    164 
    165         if ( empty( $unloaded_fonts ) ) {
    166             $unloaded_fonts = self::get_option( Settings::OMGF_OPTIMIZE_SETTING_UNLOAD_FONTS, [] );
    167         }
    168 
    169         return $unloaded_fonts;
     254        if ( empty( self::$unloaded_fonts ) ) {
     255            self::$unloaded_fonts = self::get_option( Settings::OMGF_OPTIMIZE_SETTING_UNLOAD_FONTS, [] );
     256        }
     257
     258        return apply_filters( 'omgf_filter_unloaded_fonts', self::$unloaded_fonts );
    170259    }
    171260
     
    176265     */
    177266    public static function unloaded_stylesheets() {
    178         static $unloaded_stylesheets = [];
    179 
    180         if ( empty( $unloaded_stylesheets ) ) {
     267        if ( empty( self::$unloaded_stylesheets ) ) {
    181268            // Returns a string with one empty element if the option is empty, that's why we array_filter it.
    182             $unloaded_stylesheets = explode( ',', self::get_option( Settings::OMGF_OPTIMIZE_SETTING_UNLOAD_STYLESHEETS, '' ) );
    183         }
    184 
    185         // Remove empty elements (and store it to the static variable before returning it)
    186         $unloaded_stylesheets = array_filter( $unloaded_stylesheets );
    187 
    188         return $unloaded_stylesheets;
     269            self::$unloaded_stylesheets = array_filter( explode( ',', self::get_option( Settings::OMGF_OPTIMIZE_SETTING_UNLOAD_STYLESHEETS, '' ) ) );
     270        }
     271
     272        return apply_filters( 'omgf_filter_unloaded_stylesheets', self::$unloaded_stylesheets );
    189273    }
    190274
     
    217301     */
    218302    public static function cache_keys() {
    219         static $cache_keys = [];
    220 
    221         if ( empty( $cache_keys ) ) {
    222             $cache_keys = explode( ',', self::get_option( Settings::OMGF_OPTIMIZE_SETTING_CACHE_KEYS, '' ) );
    223         }
    224 
    225         // Remove empty elements.
    226         $cache_keys = array_filter( $cache_keys );
     303        if ( empty( self::$cache_keys ) ) {
     304            // Returns a string with one empty element if the option is empty, that's why we array_filter it.
     305            self::$cache_keys = array_filter( explode( ',', self::get_option( Settings::OMGF_OPTIMIZE_SETTING_CACHE_KEYS, '' ) ) );
     306        }
    227307
    228308        /**
     
    230310         * the (default) stylesheet handles from the optimized fonts option.
    231311         */
    232         if ( empty( $cache_keys ) ) {
     312        if ( empty( self::$cache_keys ) ) {
    233313            $optimized_fonts = self::admin_optimized_fonts(); // @codeCoverageIgnore
    234314
    235             $cache_keys = array_keys( $optimized_fonts ); //@codeCoverageIgnore
    236         }
    237 
    238         return $cache_keys;
     315            self::$cache_keys = array_keys( $optimized_fonts ); //@codeCoverageIgnore
     316        }
     317
     318        return self::$cache_keys;
    239319    }
    240320
    241321    /**
    242322     * Optimized Local Fonts to be displayed in the Optimize Local Fonts table.
     323     *
    243324     * Use a static variable to reduce database reads/writes.
    244325     *
     
    253334     */
    254335    public static function admin_optimized_fonts( $maybe_add = [], $force_add = false ) {
    255         static $optimized_fonts = [];
    256 
    257         /**
    258          * Get a fresh copy from the database if $optimized_fonts is empty|null|false (on 1st run)
    259          */
    260         if ( empty( $optimized_fonts ) ) {
    261             $optimized_fonts = self::get_option( Settings::OMGF_OPTIMIZE_SETTING_OPTIMIZED_FONTS, [] );
     336        /**
     337         * Get a fresh copy from the database if self::$optimized_fonts is empty|null|false (on 1st run)
     338         */
     339        if ( empty( self::$admin_optimized_fonts ) ) {
     340            self::$admin_optimized_fonts = self::get_option( Settings::OMGF_OPTIMIZE_SETTING_OPTIMIZED_FONTS, [] );
    262341        }
    263342
     
    266345         * @since v4.5.6
    267346         */
    268         if ( is_string( $optimized_fonts ) && $optimized_fonts !== '' ) {
    269             $optimized_fonts = unserialize( $optimized_fonts ); // @codeCoverageIgnore
     347        if ( is_string( self::$admin_optimized_fonts ) && self::$admin_optimized_fonts !== '' ) {
     348            self::$admin_optimized_fonts = maybe_unserialize( self::$admin_optimized_fonts ); // @codeCoverageIgnore
    270349        }
    271350
     
    274353         * @since v4.5.7
    275354         */
    276         if ( ! empty( $maybe_add ) && ( ! isset( $optimized_fonts[ key( $maybe_add ) ] ) || $force_add ) ) {
    277             $optimized_fonts = array_merge( $optimized_fonts, $maybe_add );
    278         }
    279 
    280         return $optimized_fonts ?: [];
    281     }
    282 
    283     /**
    284      * Optimized Local Fonts to be used in the frontend. Doesn\'t contain unloaded fonts.
     355        if ( ! empty( $maybe_add ) && ( ! isset( self::$admin_optimized_fonts[ key( $maybe_add ) ] ) || $force_add ) ) {
     356            self::$admin_optimized_fonts = array_merge( self::$admin_optimized_fonts, $maybe_add );
     357        }
     358
     359        return apply_filters( 'omgf_filter_admin_optimized_fonts', self::$admin_optimized_fonts ?: [] );
     360    }
     361
     362    /**
     363     * Optimized Local Fonts to be used in the frontend. Doesn't contain unloaded fonts.
    285364     * Use a static variable to reduce database reads/writes.
    286365     *
     
    292371     * @codeCoverageIgnore
    293372     * @since v5.8.1
    294      *
    295373     */
    296374    public static function optimized_fonts( $maybe_add = [], $force_add = false ) {
    297         static $optimized_fonts = [];
    298 
    299         /**
    300          * Get a fresh copy from the database if $optimized_fonts is empty|null|false (on 1st run)
    301          */
    302         if ( empty( $optimized_fonts ) ) {
    303             $optimized_fonts = self::get_option( Settings::OMGF_OPTIMIZE_SETTING_OPTIMIZED_FONTS_FRONTEND, [] );
    304         }
    305 
    306         /**
    307          * Fallback to original Optimized Fonts table.
    308          */
    309         if ( empty( $optimized_fonts ) ) {
    310             $optimized_fonts = self::admin_optimized_fonts();
     375        /**
     376         * Get a fresh copy from the database if self::$optimized_fonts is empty|null|false (on 1st run)
     377         */
     378        if ( empty( self::$optimized_fonts ) ) {
     379            self::$optimized_fonts = self::get_option( Settings::OMGF_OPTIMIZE_SETTING_OPTIMIZED_FONTS_FRONTEND, [] );
     380        }
     381
     382        /**
     383         * Fallback to the original Optimized Fonts table.
     384         */
     385        if ( empty( self::$optimized_fonts ) ) {
     386            self::$optimized_fonts = self::admin_optimized_fonts();
    311387        }
    312388
     
    315391         * @since v4.5.6
    316392         */
    317         if ( is_string( $optimized_fonts ) && $optimized_fonts !== '' ) {
    318             $optimized_fonts = unserialize( $optimized_fonts ); // @codeCoverageIgnore
     393        if ( is_string( self::$optimized_fonts ) && self::$optimized_fonts !== '' ) {
     394            self::$optimized_fonts = maybe_unserialize( self::$optimized_fonts ); // @codeCoverageIgnore
    319395        }
    320396
     
    323399         * @since v4.5.7
    324400         */
    325         if ( ! empty( $maybe_add ) && ( ! isset( $optimized_fonts[ key( $maybe_add ) ] ) || $force_add ) ) {
    326             $optimized_fonts = array_merge( $optimized_fonts, $maybe_add );
    327         }
    328 
    329         return $optimized_fonts ?: [];
     401        if ( ! empty( $maybe_add ) && ( ! isset( self::$optimized_fonts[ key( $maybe_add ) ] ) || $force_add ) ) {
     402            self::$optimized_fonts = array_merge( self::$optimized_fonts, $maybe_add );
     403        }
     404
     405        self::$optimized_fonts = apply_filters( 'omgf_filter_optimized_fonts', self::$optimized_fonts ?: [] );
     406
     407        /**
     408         * Just to make sure that everything keeps working.
     409         */
     410        if ( has_filter( 'omgf_frontend_optimized_fonts' ) ) {
     411            _deprecated_hook( 'omgf_frontend_optimized_fonts', '6.1.4', 'omgf_filter_optimized_fonts' );
     412
     413            self::$optimized_fonts = apply_filters( 'omgf_frontend_optimized_fonts', self::$optimized_fonts );
     414        }
     415
     416        return self::$optimized_fonts;
    330417    }
    331418
     
    338425     */
    339426    public static function available_used_subsets( $maybe_add = [], $intersect = false ) {
    340         static $subsets = [];
    341 
    342         if ( empty( $subsets ) ) {
    343             $subsets = self::get_option( Settings::OMGF_AVAILABLE_USED_SUBSETS, [] );
     427        if ( empty( self::$subsets ) ) {
     428            self::$subsets = self::get_option( Settings::OMGF_AVAILABLE_USED_SUBSETS, [] );
    344429        }
    345430
     
    347432         * get_option() should take care of this, but sometimes it doesn't.
    348433         */
    349         if ( is_string( $subsets ) ) {
    350             $subsets = unserialize( $subsets ); // @codeCoverageIgnore
     434        if ( is_string( self::$subsets ) ) {
     435            self::$subsets = maybe_unserialize( self::$subsets ); // @codeCoverageIgnore
    351436        }
    352437
     
    354439         * If $maybe_add doesn't exist in the cache layer yet, add it.
    355440         */
    356         if ( ! empty( $maybe_add ) && ( ! isset( $subsets[ key( $maybe_add ) ] ) ) ) {
    357             $subsets = array_merge( $subsets, $maybe_add );
     441        if ( ! empty( $maybe_add ) && ( ! isset( self::$subsets[ key( $maybe_add ) ] ) ) ) {
     442            self::$subsets = array_merge( self::$subsets, $maybe_add );
    358443        }
    359444
     
    367452             *                              { 'Lato' => { 'latin', 'latin-ext' } }
    368453             */
    369             $filtered_subsets = apply_filters( 'omgf_available_filtered_subsets', array_values( array_filter( $subsets ) ) );
     454            $filtered_subsets = apply_filters( 'omgf_available_filtered_subsets', array_values( array_filter( self::$subsets ) ) );
    370455
    371456            self::debug_array( __( 'Filtered Subsets', 'host-webfonts-local' ), $filtered_subsets );
     
    382467        }
    383468
    384         return apply_filters( 'omgf_available_subsets', $subsets );
     469        return apply_filters( 'omgf_available_subsets', self::$subsets );
    385470    }
    386471
Note: See TracChangeset for help on using the changeset viewer.