Repository navigation
Keep font state in one place for every site, and keep every site's fonts in the 6.19 cleanup - #2004
Merged
Merged
Conversation
Contributor
|
Coverage report for commit: d507428 Summary - Lines: 93.99% | Methods: 90.96% | Branches: 85.66%
🤖 Jest coverage report |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Contributor
|
Coverage report for commit: d507428 Summary - Lines: 89.54% | Methods: 95.71%
🤖 PHPUnit coverage report |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
gravitypdf-bot
force-pushed
the
refactor/unify-multisite-fonts
branch
from
November 3, 2026 21:45
70d21df to
ca0ef98
Compare
jakejackson1
force-pushed
the
refactor/unify-multisite-fonts
branch
from
November 3, 2026 23:23
ca0ef98 to
d1ae519
Compare
gravitypdf-bot
force-pushed
the
refactor/unify-multisite-fonts
branch
from
November 4, 2026 01:40
d1ae519 to
4be62dd
Compare
This was referenced Nov 5, 2026
gravitypdf-bot
force-pushed
the
refactor/unify-multisite-fonts
branch
from
November 5, 2026 22:51
4be62dd to
50ddcb9
Compare
gravitypdf-bot
changed the base branch from
feature/core-font-upgrade-prune
to
feature/font-manager-downloaded-fonts
November 5, 2026 23:27
4 of 6 tasks
gravitypdf-bot
force-pushed
the
refactor/unify-multisite-fonts
branch
from
November 5, 2026 23:59
50ddcb9 to
0388659
Compare
4 of 5 tasks
gravitypdf-bot
added a commit
that referenced
this pull request
Nov 6, 2026
mpdf-core-fonts v1.0.0, which the Core Font installer downloaded, holds mPDF's pre-8.1.0 Garuda.ttf, whose "k" carries broken TrueType hinting (mpdf/mpdf#1440). v1.1.1 ships mPDF's fixed file, and all four Garuda faces are dehinted with it. prune() keeps a font the site needs, and the downloader skips a file that's present, so a Thai site's old Garuda would stay for good. prune() now treats Model_Font_Downloader::OUTDATED (the four Garuda files) as never kept: an unmodified v1.0.0 copy is deleted whether or not the site needs it, under the same size, hash and downloads-off checks as any other file. When a needed one goes, it queues a sync so the current file comes back in the background (the render-time finder fetches it too). The version change already queues a sync, but #2004 moves this cleanup into cron batches that can run after it. A modified Garuda, a v1.1.1 one, and one whose download is turned off stay. The other 43 dehinted fonts differ only in hinting and are left alone when kept, though the fork's character ranges files record v1.1.1 sizes, so mPDF ignores the ranges file (and logs a warning) for a kept v1.0.0 regular face. Adds the v1.0.0 (blob b9fcdfd) and v1.1.1 (blob fc4379b) Garuda.ttf as test fixtures, and moves the reset of the installer manifest stand-in into CopiesFontFixtures::use_shipped_installer_manifest(). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
jakejackson1
force-pushed
the
refactor/unify-multisite-fonts
branch
from
November 6, 2026 03:06
0388659 to
ae938cd
Compare
Base automatically changed from
feature/font-manager-downloaded-fonts
to
development
November 9, 2026 03:20
gravitypdf-bot
force-pushed
the
refactor/unify-multisite-fonts
branch
from
November 9, 2026 03:31
ae938cd to
8acc891
Compare
gravitypdf-bot
force-pushed
the
refactor/unify-multisite-fonts
branch
from
November 9, 2026 04:58
8acc891 to
1470b93
Compare
…nts in the 6.19 cleanup Every site shares the fonts folder, so the font state about it is now stored the same way on single site and Multisite: the failed downloads record and the 6.19 cleanup's progress are main network options, the language font cache is a site transient, and the failed fonts notice's dismissal lives in the record rather than in each site's settings. The 6.19 cleanup keeps the fonts any site needs, reading each site's settings, locale and PDFs directly through the same reader the Font Manager uses for other sites' fonts. It runs in a cron event that reads the sites in batches within the sync's time budget, so no upgrade request pays for a large network's scan. A malformed cleanup record is now logged and skipped rather than fatal. Adds a Multisite Playwright environment on port 8704, run as a fifth entry in the E2E matrix, and tests the failed fonts notice across sites and the network admin. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
gravitypdf-bot
force-pushed
the
refactor/unify-multisite-fonts
branch
from
November 9, 2026 05:11
19a27c0 to
d507428
Compare
gravitypdf-bot
added a commit
that referenced
this pull request
Nov 10, 2026
…e to 6.19 mpdf-core-fonts v1.0.0, which the Core Font installer downloaded, holds mPDF's pre-8.1.0 Garuda.ttf, whose "k" carries broken TrueType hinting (mpdf/mpdf#1440), and Sun-ExtA and Sun-ExtB files browsers reject as web fonts (GravityPDF/mpdf#881). prune() keeps a font the site needs, and the downloader skips a file that's present, so those copies would stay for good. The manifest moves to v1.1.2, which repairs Sun-ExtA and Sun-ExtB, and the Sun-ExtA preview opt-out goes with the fault it worked around. prune() now treats Model_Font_Downloader::OUTDATED (the four Garuda files and the two Sun-Ext files) as never kept: an unmodified v1.0.0 copy is deleted whether or not the site needs it, under the same size, hash and downloads-off checks as any other file. When a needed one goes, it queues a sync so the current file comes back in the background (the render-time finder fetches it too). The version change already queues a sync, but #2004 moves this cleanup into cron batches that can run after it. A modified copy, a current one, and one whose download is turned off stay. The other 43 dehinted fonts differ only in hinting and are left alone when kept, though the fork's character ranges files record v1.1.1 sizes, so mPDF ignores the ranges file (and logs a warning) for a kept v1.0.0 regular face. Adds the v1.0.0 (blob b9fcdfd) and v1.1.1 (blob fc4379b) Garuda.ttf as test fixtures, and moves the reset of the installer manifest stand-in into CopiesFontFixtures::use_shipped_installer_manifest(). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
gravitypdf-bot
added a commit
that referenced
this pull request
Nov 10, 2026
…e to 6.19 mpdf-core-fonts v1.0.0, which the Core Font installer downloaded, holds mPDF's pre-8.1.0 Garuda.ttf, whose "k" carries broken TrueType hinting (mpdf/mpdf#1440), and Sun-ExtA and Sun-ExtB files browsers reject as web fonts (GravityPDF/mpdf#881). prune() keeps a font the site needs, and the downloader skips a file that's present, so those copies would stay for good. The manifest moves to v1.1.2, which repairs Sun-ExtA and Sun-ExtB, and the Sun-ExtA preview opt-out goes with the fault it worked around. prune() now treats Model_Font_Downloader::OUTDATED (the four Garuda files and the two Sun-Ext files) as never kept: an unmodified v1.0.0 copy is deleted whether or not the site needs it, under the same size, hash and downloads-off checks as any other file. When a needed one goes, it queues a sync so the current file comes back in the background (the render-time finder fetches it too). The version change already queues a sync, but #2004 moves this cleanup into cron batches that can run after it. A modified copy, a current one, and one whose download is turned off stay. The other 43 dehinted fonts differ only in hinting and are left alone when kept, though the fork's character ranges files record v1.1.1 sizes, so mPDF ignores the ranges file (and logs a warning) for a kept v1.0.0 regular face. Bumps the mPDF fork to 725098a for GravityPDF/mpdf#883, whose ranges files record the repaired sizes and whose TTFontFile reads Sun-ExtA with OTL on. The fork no longer uses myclabs/deep-copy, which is now only PHPUnit's, so it stops being scoped or stripped from vendor/. Adds the v1.0.0 (blob b9fcdfd) and v1.1.1 (blob fc4379b) Garuda.ttf as test fixtures, and moves the reset of the installer manifest stand-in into CopiesFontFixtures::use_shipped_installer_manifest(). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
gravitypdf-bot
added a commit
that referenced
this pull request
Nov 10, 2026
…e to 6.19 mpdf-core-fonts v1.0.0, which the Core Font installer downloaded, holds mPDF's pre-8.1.0 Garuda.ttf, whose "k" carries broken TrueType hinting (mpdf/mpdf#1440), and Sun-ExtA and Sun-ExtB files browsers reject as web fonts (GravityPDF/mpdf#881). prune() keeps a font the site needs, and the downloader skips a file that's present, so those copies would stay for good. The manifest moves to v1.1.2, which repairs Sun-ExtA and Sun-ExtB, and the Sun-ExtA preview opt-out goes with the fault it worked around. prune() now treats Model_Font_Downloader::OUTDATED (the four Garuda files and the two Sun-Ext files) as never kept: an unmodified v1.0.0 copy is deleted whether or not the site needs it, under the same size, hash and downloads-off checks as any other file. When a needed one goes, it queues a sync so the current file comes back in the background (the render-time finder fetches it too). The version change already queues a sync, but #2004 moves this cleanup into cron batches that can run after it. A modified copy, a current one, and one whose download is turned off stay. The other 43 dehinted fonts differ only in hinting and are left alone when kept, though the fork's character ranges files record v1.1.1 sizes, so mPDF ignores the ranges file (and logs a warning) for a kept v1.0.0 regular face. Bumps the mPDF fork to 725098a for GravityPDF/mpdf#883, whose ranges files record the repaired sizes and whose TTFontFile reads Sun-ExtA with OTL on. The fork no longer uses myclabs/deep-copy, so the plugin requires it directly to keep GFPDF_Vendor\DeepCopy available to add-ons and custom templates, and a scoper patcher deprecates its constructor ahead of its removal in 7.0. Adds the v1.0.0 (blob b9fcdfd) and v1.1.1 (blob fc4379b) Garuda.ttf as test fixtures, and moves the reset of the installer manifest stand-in into CopiesFontFixtures::use_shipped_installer_manifest(). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
jakejackson1
pushed a commit
that referenced
this pull request
Nov 10, 2026
…e to 6.19 mpdf-core-fonts v1.0.0, which the Core Font installer downloaded, holds mPDF's pre-8.1.0 Garuda.ttf, whose "k" carries broken TrueType hinting (mpdf/mpdf#1440), and Sun-ExtA and Sun-ExtB files browsers reject as web fonts (GravityPDF/mpdf#881). prune() keeps a font the site needs, and the downloader skips a file that's present, so those copies would stay for good. The manifest moves to v1.1.2, which repairs Sun-ExtA and Sun-ExtB, and the Sun-ExtA preview opt-out goes with the fault it worked around. prune() now treats Model_Font_Downloader::OUTDATED (the four Garuda files and the two Sun-Ext files) as never kept: an unmodified v1.0.0 copy is deleted whether or not the site needs it, under the same size, hash and downloads-off checks as any other file. When a needed one goes, it queues a sync so the current file comes back in the background (the render-time finder fetches it too). The version change already queues a sync, but #2004 moves this cleanup into cron batches that can run after it. A modified copy, a current one, and one whose download is turned off stay. The other 43 dehinted fonts differ only in hinting and are left alone when kept, though the fork's character ranges files record v1.1.1 sizes, so mPDF ignores the ranges file (and logs a warning) for a kept v1.0.0 regular face. Bumps the mPDF fork to 725098a for GravityPDF/mpdf#883, whose ranges files record the repaired sizes and whose TTFontFile reads Sun-ExtA with OTL on. The fork no longer uses myclabs/deep-copy, so the plugin requires it directly to keep GFPDF_Vendor\DeepCopy available to add-ons and custom templates, and a scoper patcher deprecates its constructor ahead of its removal in 7.0. Adds the v1.0.0 (blob b9fcdfd) and v1.1.1 (blob fc4379b) Garuda.ttf as test fixtures, and moves the reset of the installer manifest stand-in into CopiesFontFixtures::use_shipped_installer_manifest(). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Every site on an install shares one fonts folder, so this PR treats all font state about that folder as install-wide and stores it the same way on single site and Multisite. That removes the "network-wide here, per site there" splits the stack added. What a site needs (its default font, locale and PDF fonts) stays per site, but the 6.19 cleanup, which deletes from the shared folder, now keeps every site's fonts rather than only those of the site whose request ran the upgrade.
gfpdf_core_font_failures) and the 6.19 cleanup's progress (gfpdf_core_font_cleanup) are main network options on both setups. Theis_multisite()write branch and the "store it empty so it's autoloaded" seed are gone.dismissedflag per file), not in each site'saction_dismissal. Dismissing it once hides it for every site and the network admin, and a font that gives up again later is listed again.switch_to_blog().gfpdf_core_font_cleanup_runcron event reads the sites in batches within the sync's 20-second budget, rescheduling itself until every site is read, then cleans the folder. A file written after the cleanup was queued is kept, as a site may have downloaded it since its settings were read.remove_font_state(), on both setups. The single-site-only back-off sweep and the font keys in the Multisite sitemeta sweep are gone.Try it
wp-content/uploads/PDF_EXTENDED_TEMPLATES/fonts/.gfpdf_current_versionto6.18.0on site A and load its admin. Nothing is removed until cron runsgfpdf_core_font_cleanup_run(e.g.wp cron event run gfpdf_core_font_cleanup_run). Then the folder keeps the DejaVu Serif Condensed, Free Serif and DejaVu Sans Condensed files, and nothing else from the core set. Loading site B's admin afterwards removes nothing more.raw.githubusercontent.com(e.g. withpre_http_request), choose a font that isn't on disk on site A and let its sync retry until it gives up. The notice appears on both sites and in the network admin. Dismissing it on site B hides it everywhere.Test plan
chmod):test_an_unwritable_folder_fails_without_a_request×2.prune()keeps files written since the time given.truedismissal counts; the language cache is shared and the locale isn't cached; uninstall removes the language cache and the cleanup's progress, and clears its event.yarn test:e2e:multisite: the failed fonts notice on the main site, a subsite and the network admin, with an image snapshot; an editor doesn't see it; a subsite admin's dismissal hides it everywhere; only a font that fails later is listed again.yarn test:e2e: 131 of 131 pass. The failed fonts notice test now keeps its dismissal in an option of its own (tools/mu-plugins/gravitypdf.php), as the fixed failures record can't hold thedismissedflag.More info
The model. The fonts folder lives in the main site's uploads, so one folder serves every site on every network. State about the folder (what failed, what was cleaned, which languages are installed) is install-wide. What a site wants stays per site and is read from its own settings and forms. Anything that deletes from the folder has to consider every site; anything that only adds (the background sync, a render-time download) can act on the current site's needs alone.
Each decision and its trade-off
get_network_option( get_main_network_id(), … ). On single site that's the options table, and on Multisite it's the main network's sitemeta, so a multi-network install also has one record and one cleanup for its one folder. Trade-off:update_network_option()stores the option with autoload off on a single site. The notice check therefore now costs one primary-key query, cached for the request, on admin pages that can show notices and only for users with the settings capability. Multisite has always paid that. Keeping autoload would have needed theis_multisite()branch this PR removes.dismissedflag on each record entry. Behaviour change: dismissal is shared. Any admin with the capability, including a subsite admin, hides the notice for everyone, including the network admin. The System Report row still lists the failed fonts. Previously each site kept its own dismissal, and the network admin's went into the main site's settings.Model_Actions::FAILED_CORE_FONT_DISMISSALandget_failed_core_font_dismissal()are gone; neither was released.WP_LANG_DIR, which every site shares, so their keys are cached in a site transient.get_locale()is per site and can be set without its pack, so it's mapped on each request without being cached (one in-memory lookup). Flushing on a language pack install now clears it for every site.Model_Required_Fonts::get_site_font_keys( $site_id, $unset_default ), shared with the Font Manager's "in use" check (this PR adds the optional$unset_default), reads one site, andget_install_font_files( $keys )turns the keys gathered into files, adding the installed languages'. For each site it runs one options query (gfpdf_settings,gf_db_version,WPLANG) and the existing paged form-meta scan against that site's table prefix, skipping the scan for sites withoutgf_db_version. There is no separate table check.Model_Font_Downloader::PRE_6_19_DEFAULT_FONT, moved from the upgrade routines so the cleanup can read it without storing it), because a site that hasn't upgraded yet will save that.schedule_cleanup()storesstarted, every site's ID (get_sites()across all networks, or the current blog) and the keys found so far in thegfpdf_core_font_cleanupmain network option, then queuesgfpdf_core_font_cleanup_runon the site whose request ran the upgrade. Each run reads the sites left through the sync's budget loop (within_budget(), now shared, at least one site per run) and saves the ones it didn't reach. The last run prunes and sets the option totrue, which later upgrades skip.prune( $keep, $since )keeps by modification time. If the event is lost before it finishes (e.g. the hosting site is deleted), the folder is simply never cleaned.schedule_by()takes the event, so both events use its "never two, never later" scheduling; its warning is nowFont event could not be scheduledwith the event as context.Controller_Upgrade_Routines::remove_unneeded_core_fonts()is nowschedule_core_font_cleanup(), and Remove the core fonts a new install wouldn't have on the upgrade to 6.19 #1998'sModel_Font_Downloader::PRUNEDmultisite flag is replaced byModel_Font_Downloader::CLEANUP.prune()takes an optional$sinceafter$keep.SYNC_REMAINING: still per site. Each site's cron downloads what that site needs, which only ever adds files.remove_font_state()runs on both setups. It deletes the main network's failures and cleanup flag, the language cache, and each manifest file's back-off by exact key (no table-specificLIKE).remove_font_back_offs()is gone; it was single-site only and never released. The Multisite sitemeta sweep is back to licence caches and the rich text flag. On a multi-network install, back-offs on other networks are left to expire.cleanup()logs a warning and returns, rather than defaulting the missing fields, as a default would makeprune()delete too much. The record stays as it is, so that install's folder is simply never cleaned.tools/wp-env/e2e-multisite.json(port 8704) andtools/playwright/config-multisite.tsruntests/playwright/multisite/as a fifth entry in thee2e-playwrightmatrix. It's a separate Playwright config becausewpCli()targets one environment per run.is_multisite()branch inModel_Font_Sources::remove_record(), which keeps an adopted record's files on Multisite in case another site's record uses them. Removing it needs the other-sites file check from plan §10 ("Multisite-safe font CRUD"). That is planned as its own Bug PR so it can be backported to 6.18.x alone, so it's left there. Until then, a suffixed copy adopted on Multisite stays on disk as an orphan.$wp_rewriteand$wp_settings_errorsintear_down().