Skip to content

Comments

Merge latest test changes into main#6

Open
anthonythorne wants to merge 9 commits intomainfrom
test
Open

Merge latest test changes into main#6
anthonythorne wants to merge 9 commits intomainfrom
test

Conversation

@anthonythorne
Copy link
Member

@anthonythorne anthonythorne commented Feb 3, 2026

Summary by CodeRabbit

  • Documentation
    • Expanded guides for installation, block editor, webpack and filters with performance best practices, troubleshooting and guidance for copying block assets.
  • New Features
    • Support for configurable block asset source/destination patterns and improved block-asset copying behaviour.
  • Performance
    • Build-signature aware caching, request-level guards, cached block metadata, batched block/content checks and asset-data caching.
  • Maintenance
    • Changelog added and package version bumped.

- Add caching for asset lookups, template scans, and block registry
- Implement build signature auto-invalidation for cache busting
- Add request-level guards to prevent redundant block registrations
- Optimise dynamic block detection with batched has_block() calls
- Add cache flush helper and update documentation
- Create vendor-specific cursor rule file

Reduces filesystem operations from hundreds to cached lookups per request.
- Add debug logging with request ID grouping (ENQUEUES_DEBUG)
@anthonythorne anthonythorne changed the title Test Merge latest test changes into main Feb 3, 2026
@coderabbitai
Copy link

coderabbitai bot commented Feb 3, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds build-signature–aware caching and debug utilities, per-request guards and transient-backed block registration caching with flush hooks, asset-resolution caching (including negative lookups), new CopyWebpackPlugin block-assets patterns, and expanded UK‑English documentation on caching, performance and Webpack configuration.

Changes

Cohort / File(s) Summary
Documentation & Rules
\.cursor/rules/enqueues.mdc, docs/BLOCK-EDITOR.md, docs/FILTERS.md, docs/THEME-ASSETS.md, docs/WEBPACK.md, docs/WEBPACK-VS-WP-SCRIPTS.md
Large editorial additions and British‑English changes: new installation/usage guide, expanded caching & performance sections, block‑editor performance notes, filter docs, CopyWebpackPlugin block-assets examples, and spelling/terminology updates.
Webpack / CopyPlugin Patterns (JS)
src/js/enqueues-copy-plugin-config-pattern.js
Added getCopyPluginConfigBlockAssetsPattern(); renamed parameters from blockDir to srcBlockDir/distBlockDir; added 'block-assets' context; updated block-json and render-php signatures to accept src/dist block dir parameters.
Cache Utilities (PHP)
src/php/Function/Cache.php
Added debug helpers (is_debug_enabled, get_request_id, get_page_context, debug_log), cache controls (is_cache_enabled, get_cache_ttl), build‑signature computation (get_enqueues_build_signature) and flush_enqueues_cache() with transient cleanup and hooks.
Asset Functions (PHP)
src/php/Function/Assets.php
Made asset resolution build‑signature aware; added positive and negative caching with signature keys, added get_asset_block_editor_file_data, and adjusted inline render formatting.
Block Editor Registration (PHP)
src/php/Controller/BlockEditorRegistrationController.php
Added transient-backed block metadata cache keyed by build signature, per‑request guard, register_blocks_from_cache() and flush_block_cache() methods/hooks, block asset versioning, batched has_block() checks for dynamic block styles, and cache hit/miss logging.
Enqueue Assets Library (PHP)
src/php/Library/EnqueueAssets.php
Reworked caching keys to include build signature and locale/site context for template and asset discovery; added debug logging on cache hits/misses.
Env change
src/php/Function/Env.php
is_local() now checks for a global is_local function name rather than namespaced variant.
Changelog & Version
CHANGELOG.md, composer.json
Bumped package to 1.3.4; changelog entry for enhanced copy‑plugin patterns and fix for src path handling.

Sequence Diagrams

sequenceDiagram
    participant Request as HTTP Request
    participant Controller as BlockEditorRegistrationController
    participant Cache as WP Transient Cache
    participant FS as Filesystem
    participant Registry as Block Type Registry

    Request->>Controller: register_blocks()
    Controller->>Controller: Check per-request guard
    alt Already processed
        Controller-->>Request: Return (skip)
    else First processing
        Controller->>Controller: Build cache key (build signature + blocks root)
        Controller->>Cache: Load cached metadata
        alt Cache hit
            Cache-->>Controller: Return cached blocks metadata
            Controller->>Registry: register_block_type_from_metadata()
            Registry-->>Controller: Success / already-registered
            Controller->>Controller: Log cache hit
        else Cache miss
            Controller->>FS: Scan block directories for metadata
            FS-->>Controller: Block metadata
            Controller->>Registry: register_block_type_from_metadata()
            Registry-->>Controller: Success
            Controller->>Cache: Store metadata transient (signature key)
            Controller->>Controller: Log cache miss
        end
        Controller->>Controller: Engage per-request guard
    end
Loading
sequenceDiagram
    participant Caller as Caller
    participant Signature as get_enqueues_build_signature()
    participant AssetFunc as asset_find_file_path()
    participant Cache as WP Transient
    participant FS as Filesystem

    Caller->>Signature: Request build signature
    Signature-->>Caller: Return signature
    Caller->>AssetFunc: Request file path
    AssetFunc->>AssetFunc: Build signature-aware cache key
    AssetFunc->>Cache: Lookup cached path
    alt Cache hit
        Cache-->>AssetFunc: Return cached path (or false)
        AssetFunc-->>Caller: Return cached result
    else Cache miss
        AssetFunc->>FS: Scan filesystem for file
        FS-->>AssetFunc: File path or not-found
        AssetFunc->>Cache: Store result (positive or negative) with signature
        AssetFunc-->>Caller: Return path or false
    end
Loading
sequenceDiagram
    participant Deploy as Deployment
    participant BuildSig as Build Signature
    participant Hook as Hook (enqueues_flush_block_cache / after_switch_theme)
    participant Controller as BlockEditorRegistrationController
    participant Cache as WP Transient

    Deploy->>BuildSig: Asset mtimes change
    BuildSig->>Cache: New keys produced (implicit invalidation)
    Hook->>Controller: flush_block_cache()
    Controller->>Cache: Delete block registry transient(s)
    Cache-->>Controller: Confirm deletion
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 I hopped through mtimes, keys and trails,

Cached my carrots in transient bales,
Guards engaged, I only run once,
Blocks and assets now found at once,
A fresher build — hop, flush and sail! 🥕✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'Merge latest test changes into main' is vague and generic, using non-descriptive terms that don't convey meaningful information about the substantial changes in the changeset, such as caching architecture, build-signature invalidation, or documentation updates. Provide a more specific and descriptive title that reflects the primary changes, such as 'Add build-signature caching and block editor optimisations' or 'Implement caching architecture and asset versioning for block editor registration'.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch test

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Fix all issues with AI agents
In `@docs/BLOCK-EDITOR.md`:
- Around line 100-107: Update the Cache Management note to clarify how theme
changes trigger cache invalidation: either replace the vague "Automatic
invalidation on theme switch" line with the concrete WordPress hook name (e.g.,
mention the switch_theme action) and explain that enqueues_flush_block_cache is
fired on switch_theme, or remove the claim; reference the
enqueues_flush_block_cache action and the switch_theme hook so readers know
which hook drives the cache flush.

In `@docs/FILTERS.md`:
- Around line 103-105: The docs list exposes an internal
helper—get_enqueues_build_signature()—as if public; update the FILTERS.md
section so the Cache Helper Functions subsection is explicitly marked
Internal/Advanced (or move the get_enqueues_build_signature() entry under an
existing Internal section), and remove or hide it from the public index;
reference the symbol name get_enqueues_build_signature() (and keep
flush_enqueues_cache() public if intended) and add a short “Internal — do not
use” note to make visibility explicit.

In `@docs/THEME-ASSETS.md`:
- Around line 150-156: The line "Use filters for customisation" uses British
spelling while the document uses "Customizing" elsewhere; update that phrase to
"Use filters for customization" so the spelling matches the "Customizing"
headings and maintain consistency across the document (search for the exact
phrase "Use filters for customisation" and replace with "Use filters for
customization").

In `@src/js/enqueues-copy-plugin-config-pattern.js`:
- Around line 113-119: The replacement logic in
getCopyPluginConfigBlockAssetsPattern uses a hard-coded `${rootDir}/src/` which
breaks when srcDirPattern is customized; update the to: function to compute the
destination using the actual srcDirPattern and blockDir (or simply use
path.relative) instead of the hard-coded string: derive the source base by
joining rootDir and srcDirPattern (and blockDir if needed) and call
path.relative(sourceBase, pathContext.absoluteFilename) then join that relative
path onto distDir to produce the correct output path; update references to
rootDir, distDir, srcDirPattern, blockDir and pathContext.absoluteFilename
accordingly.

Comment on lines +103 to +105
**Cache Helper Functions:**
- `\Enqueues\flush_enqueues_cache()`: Flush all Enqueues-related caches
- `\Enqueues\get_enqueues_build_signature()`: Get current build signature (internal)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Make internal helper visibility explicit.

get_enqueues_build_signature() is noted as internal but appears in the public index. Consider tagging this subsection as Internal/Advanced (or moving it under an internal section) to prevent misuse.

🤖 Prompt for AI Agents
In `@docs/FILTERS.md` around lines 103 - 105, The docs list exposes an internal
helper—get_enqueues_build_signature()—as if public; update the FILTERS.md
section so the Cache Helper Functions subsection is explicitly marked
Internal/Advanced (or move the get_enqueues_build_signature() entry under an
existing Internal section), and remove or hide it from the public index;
reference the symbol name get_enqueues_build_signature() (and keep
flush_enqueues_cache() public if intended) and add a short “Internal — do not
use” note to make visibility explicit.

Comment on lines 150 to 156
### Performance Best Practices

1. **Always use Enqueues helpers**: `asset_find_file_path()` and `get_asset_page_type_file_data()` are cached and optimized
2. **Avoid direct filesystem calls**: Use Enqueues functions instead of `file_exists()`, `filemtime()`, etc.
3. **Leverage caching**: Results are automatically cached, so repeated calls are fast
4. **Respect build signatures**: Cache keys include build signatures, so caches auto-invalidate on deployments
5. **Use filters for customisation**: Don't bypass the system; use filters to modify behavior
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Standardise spelling in the performance list.

Line 156 uses “customisation” while earlier headings use “Customizing”. Please standardise on one variant for consistency.

✏️ Suggested tweak
-5. **Use filters for customisation**: Don't bypass the system; use filters to modify behavior
+5. **Use filters for customization**: Don't bypass the system; use filters to modify behavior
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
### Performance Best Practices
1. **Always use Enqueues helpers**: `asset_find_file_path()` and `get_asset_page_type_file_data()` are cached and optimized
2. **Avoid direct filesystem calls**: Use Enqueues functions instead of `file_exists()`, `filemtime()`, etc.
3. **Leverage caching**: Results are automatically cached, so repeated calls are fast
4. **Respect build signatures**: Cache keys include build signatures, so caches auto-invalidate on deployments
5. **Use filters for customisation**: Don't bypass the system; use filters to modify behavior
### Performance Best Practices
1. **Always use Enqueues helpers**: `asset_find_file_path()` and `get_asset_page_type_file_data()` are cached and optimized
2. **Avoid direct filesystem calls**: Use Enqueues functions instead of `file_exists()`, `filemtime()`, etc.
3. **Leverage caching**: Results are automatically cached, so repeated calls are fast
4. **Respect build signatures**: Cache keys include build signatures, so caches auto-invalidate on deployments
5. **Use filters for customization**: Don't bypass the system; use filters to modify behavior
🧰 Tools
🪛 LanguageTool

[uncategorized] ~156-~156: Do not mix variants of the same word (‘customisation’ and ‘customization’) within a single text.
Context: ...ate on deployments 5. Use filters for customisation: Don't bypass the system; use filters...

(EN_WORD_COHERENCY)

🤖 Prompt for AI Agents
In `@docs/THEME-ASSETS.md` around lines 150 - 156, The line "Use filters for
customisation" uses British spelling while the document uses "Customizing"
elsewhere; update that phrase to "Use filters for customization" so the spelling
matches the "Customizing" headings and maintain consistency across the document
(search for the exact phrase "Use filters for customisation" and replace with
"Use filters for customization").

add configurable src/dist block dirs and assets dir
fix block asset destination paths for custom src patterns
update webpack docs and AU English copy
bump version to 1.3.4 and update changelog
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
docs/THEME-ASSETS.md (1)

11-16: ⚠️ Potential issue | 🟡 Minor

Keep British spelling consistent in headings.

Line 11 switches to British spelling, but later headings still say “Localize Data”. Consider updating those headings to “Localise Data” to avoid mixed variants (filter names can remain unchanged).

✏️ Suggested tweak
-### Example: Localizing Data for Main JS
+### Example: Localising Data for Main JS
@@
-### Example: Localize Data
+### Example: Localise Data

- Add block editor asset data helper and use it for plugin/extension enqueues
- Override block registration version using compiled asset versions
- Standardise block.json version to 1.0.0
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@src/php/Controller/BlockEditorRegistrationController.php`:
- Around line 350-363: flush_block_cache currently computes the cache key using
the current get_enqueues_build_signature() so it cannot delete the old transient
created under a previous build signature; update flush_block_cache to also read
a persistent "latest cache key" transient (e.g., a transient named like
'enqueues_block_registry_latest_key') and delete that transient value and the
transient it points to, and ensure that wherever the block registry transient is
created (the code that sets the 'enqueues_block_registry_' . md5(...) key) also
writes this latest key transient so flush_block_cache can reliably locate and
delete the prior build's cache entry using delete_transient and then optionally
delete the latest-key transient itself.

In `@src/php/Function/Assets.php`:
- Around line 269-272: The negative cache currently stores literal false which
collides with transient misses; update both functions
get_asset_page_type_file_data and get_asset_block_editor_file_data to store a
sentinel (e.g., '__not_found__' or an empty array) instead of false when an
asset is not found, and change the cache-hit checks (the existing false !==
$cached_data check near the earlier cache-read in get_asset_page_type_file_data
and the analogous check in get_asset_block_editor_file_data) to detect the
sentinel and treat it as a negative cache hit (return not-found result) while
still honoring genuinely cached data values.
🧹 Nitpick comments (5)
src/php/Function/Assets.php (2)

200-267: Duplicated asset-data construction and versioning logic between primary and fallback paths.

The block at lines 200–227 (primary file) and 237–264 (fallback file) are near-identical: build $data array → load .asset.php → set ver from asset manifest or filemtime → cache. The same pattern appears again in get_asset_block_editor_file_data (lines 326–349).

Consider extracting a shared helper, e.g. build_asset_data( $directory, $directory_uri, $compiled_file_path, $file_ext, $handle_name ), that all three call sites delegate to. This would reduce the maintenance surface and risk of the three copies drifting out of sync.


334-336: str_replace('.js', '.asset.php', …) replaces all occurrences, not just the extension.

If $compiled_file_path ever contains .js earlier in the path (e.g., a directory named foo.js), the replacement would corrupt the path. Using a regex anchored to the end, or preg_replace, is safer:

-$asset_php_path = "{$directory}/" . ltrim( str_replace( '.js', '.asset.php', $compiled_file_path ), '/' );
+$asset_php_path = "{$directory}/" . ltrim( preg_replace( '/\.js$/', '.asset.php', $compiled_file_path ), '/' );

Low probability in practice, but worth hardening since this is a new function.

src/php/Controller/BlockEditorRegistrationController.php (3)

130-146: Hook wiring looks solid — good use of after_switch_theme and a custom action for cache invalidation.

One small note: set_block_metadata_version and set_block_asset_version both call get_block_asset_version for the same block, performing the same loop over asset keys. The inner get_asset_block_editor_file_data calls will hit the transient cache on the second pass, so runtime cost is low, but there is duplicated iteration overhead per block. Consider memoising get_block_asset_version results in a class property if the block count grows large.


166-205: Cache-hit path still performs a full glob() via register_blocks_from_cache.

The transient caches handle metadata (dynamic/static classification, asset handles) but register_blocks_from_cache still calls glob("{$blocks_root}/*") and file_exists per block directory. This means the filesystem scan isn't actually avoided on a cache hit — only the handle-extraction logic is skipped.

If the glob results themselves were cached (i.e., the list of block directories/metadata files), you could skip the glob on a cache hit and iterate over the cached list directly. This would provide a more meaningful I/O reduction, particularly on hosts with slow filesystem access.

Not critical — the current approach is correct and the handle-caching is valuable — but worth noting for future optimisation.


413-432: Unused $file parameter flagged by static analysis.

The block_type_metadata filter passes the file path as the second argument, so the parameter must be in the signature to satisfy the callback contract. Suppress the warning to signal intent.

Proposed fix
-	public function set_block_metadata_version( array $metadata, string $file = '' ): array {
+	public function set_block_metadata_version( array $metadata, string $file = '' ): array { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed -- Required by block_type_metadata filter signature.

Or, if PHPMD is the primary concern, use @SuppressWarnings:

+	/** `@SuppressWarnings`(PHPMD.UnusedFormalParameter) */
 	public function set_block_metadata_version( array $metadata, string $file = '' ): array {

Comment on lines +350 to 363
public function flush_block_cache(): void {
$directory = get_template_directory();
$block_editor_dist_dir_path = get_block_editor_dist_dir();
$blocks_root = "{$directory}{$block_editor_dist_dir_path}/blocks";

if ( ! is_dir( $blocks_root ) ) {
return;
}

$build_signature = get_enqueues_build_signature();
$cache_key = 'enqueues_block_registry_' . md5( "{$blocks_root}:{$build_signature}" );

delete_transient( $cache_key );
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

flush_block_cache uses the current build signature — stale keys from a previous build won't be deleted.

After a deployment that changes asset files, get_enqueues_build_signature() produces a new signature, so the cache key computed here won't match the old transient. The old entry simply expires via TTL, while the new signature causes a natural cache miss and re-scan.

This is functionally correct (no stale data served), but flush_block_cache becomes a no-op post-deployment since the new-signature key doesn't exist yet. If explicit flushing is important (e.g., for admin tooling), consider also storing a known "latest cache key" transient so the flush can target it reliably.

🤖 Prompt for AI Agents
In `@src/php/Controller/BlockEditorRegistrationController.php` around lines 350 -
363, flush_block_cache currently computes the cache key using the current
get_enqueues_build_signature() so it cannot delete the old transient created
under a previous build signature; update flush_block_cache to also read a
persistent "latest cache key" transient (e.g., a transient named like
'enqueues_block_registry_latest_key') and delete that transient value and the
transient it points to, and ensure that wherever the block registry transient is
created (the code that sets the 'enqueues_block_registry_' . md5(...) key) also
writes this latest key transient so flush_block_cache can reliably locate and
delete the prior build's cache entry using delete_transient and then optionally
delete the latest-key transient itself.

Comment on lines +269 to +272
// Cache negative result to avoid repeated lookups.
if ( is_cache_enabled() ) {
set_transient( $cache_key, false, get_cache_ttl() );
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Negative cache with false is indistinguishable from a transient miss.

get_transient() returns false both when the key doesn't exist and when the stored value is literally false. Storing false on line 271 means the check on line 158 (false !== $cached_data) will never recognise a negative cache hit — every "not found" asset will re-execute the full lookup on every request, defeating the purpose of the negative cache.

The same issue applies to get_asset_block_editor_file_data at line 356.

Use a sentinel value (e.g., '__not_found__' or an empty array) instead, so negative results are actually cached.

Proposed fix for both functions

In get_asset_page_type_file_data:

 	// Cache negative result to avoid repeated lookups.
 	if ( is_cache_enabled() ) {
-		set_transient( $cache_key, false, get_cache_ttl() );
+		set_transient( $cache_key, '__not_found__', get_cache_ttl() );
 	}

And update the cache-hit check near line 158:

 	if ( is_cache_enabled() ) {
 		$cached_data = get_transient( $cache_key );
 		if ( false !== $cached_data ) {
+			if ( '__not_found__' === $cached_data ) {
+				return false;
+			}
 			return $cached_data;
 		}
 	}

Apply the same pattern in get_asset_block_editor_file_data (lines 312–317 and 354–357).

🤖 Prompt for AI Agents
In `@src/php/Function/Assets.php` around lines 269 - 272, The negative cache
currently stores literal false which collides with transient misses; update both
functions get_asset_page_type_file_data and get_asset_block_editor_file_data to
store a sentinel (e.g., '__not_found__' or an empty array) instead of false when
an asset is not found, and change the cache-hit checks (the existing false !==
$cached_data check near the earlier cache-read in get_asset_page_type_file_data
and the analogous check in get_asset_block_editor_file_data) to detect the
sentinel and treat it as a negative cache hit (return not-found result) while
still honoring genuinely cached data values.

- add block asset data helper and use it for block editor enqueues
- override block metadata version with compiled asset versions
- improve build signature caching and extend TTL
-
- always clean dist before theme builds
- document cache invalidation and performance behaviour
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@docs/THEME-ASSETS.md`:
- Around line 140-146: The docs show ENQUEUES_CACHE_TTL default as 12 hours but
get_cache_ttl() in src/php/Function/Cache.php uses DAY_IN_SECONDS (24 hours);
update the documentation in docs/THEME-ASSETS.md so the comment and example
match the code (change the comment to "default: 24 hours" and adjust the example
TTL expression to 24 * HOUR_IN_SECONDS or DAY_IN_SECONDS) so ENQUEUES_CACHE_TTL
and get_cache_ttl() are consistent.

In `@src/php/Function/Assets.php`:
- Around line 242-253: The fallback if-block in Assets.php has an extra leading
tab causing inconsistent indentation; locate the block that checks if ( ! empty(
$fallback_compiled_file_path ) ) (referenced by variables
$fallback_compiled_file_path, $full_file_path, $file_mtime, $is_minified and the
$data array) and normalize its indentation to match the surrounding function
(align the if, its opening brace, inner lines and closing brace with the rest of
the function) so the block’s whitespace matches other blocks and removes the
merge-artifact tab.
🧹 Nitpick comments (4)
src/php/Function/Assets.php (2)

12-16: Redundant use imports — these functions are already in the Enqueues namespace.

Since the file declares namespace Enqueues; at line 10, functions like is_cache_enabled(), get_cache_ttl(), etc., which are also in the Enqueues namespace, are resolved automatically. The use function statements are unnecessary (though harmless).


195-205: Cache check happens after file resolution — asset_find_file_path() runs on every call regardless.

The cache key at line 197 depends on $effective_compiled_file_path, which is computed by calling asset_find_file_path() at lines 180 and 190. This means the potentially expensive file-path resolution runs before the cache is ever consulted. Even though asset_find_file_path() has its own internal cache, the composite cache key design here undermines the purpose of caching get_asset_page_type_file_data as a whole — filter calls (lines 156–177) and the file_exists at line 183 still execute on every request.

Consider building the cache key from the input parameters alone (without $effective_compiled_file_path) so the transient lookup can short-circuit earlier.

src/php/Controller/BlockEditorRegistrationController.php (2)

166-288: Solid caching and guard logic for block registration.

The static $registered guard, cache-miss scanning, and cache-hit reuse are well-structured. A few observations:

  1. The cache stores $this->blocks (handle metadata) but register_blocks_from_cache() still performs a glob() + file_exists() per block (lines 308–314). The filesystem scan isn't fully eliminated on cache hits — consider caching the list of block directories/metadata files as well for a more complete bypass.
  2. On cache miss (line 274), the transient is written regardless of whether any blocks were found. This is fine — an empty $this->blocks structure is a valid cached state.

Overall, good improvement for repeat-request performance.


413-465: set_block_metadata_version and set_block_asset_version are near-identical — extract shared logic.

Both methods perform the same namespace guard, slug extraction, and get_block_asset_version call. The only difference is which array key receives the version ($metadata['version'] vs $settings['version']). Consider extracting the common preamble into a small private helper.

The unused $file parameter on line 413 is required by the block_type_metadata filter contract, so the PHPMD warning can be suppressed with a @SuppressWarnings annotation or a brief inline comment.

♻️ Example helper extraction
+	/**
+	 * Resolve asset version for a block if it belongs to this namespace.
+	 *
+	 * `@param` array $metadata Block metadata.
+	 * `@return` string|int|null Version string/int, or null if not applicable.
+	 */
+	private function resolve_block_asset_version( array $metadata ): string|int|null {
+		if ( empty( $metadata['name'] ) ) {
+			return null;
+		}
+		$namespace = get_block_editor_namespace();
+		if ( 0 !== strpos( $metadata['name'], "{$namespace}/" ) ) {
+			return null;
+		}
+		$block_slug = basename( str_replace( '/', DIRECTORY_SEPARATOR, $metadata['name'] ) );
+		$version    = $this->get_block_asset_version( $block_slug, $metadata );
+		return $version ?: null;
+	}
+
 	public function set_block_metadata_version( array $metadata, string $file = '' ): array {
-		if ( empty( $metadata['name'] ) ) {
-			return $metadata;
-		}
-		$namespace = get_block_editor_namespace();
-		if ( 0 !== strpos( $metadata['name'], "{$namespace}/" ) ) {
-			return $metadata;
-		}
-		$block_parts = explode( '/', $metadata['name'] );
-		$block_slug  = end( $block_parts );
-		$asset_version = $this->get_block_asset_version( $block_slug, $metadata );
+		$asset_version = $this->resolve_block_asset_version( $metadata );
 		if ( $asset_version ) {
 			$metadata['version'] = (string) $asset_version;
 		}
 		return $metadata;
 	}

Comment on lines +140 to +146
```php
// Enable caching (default: true)
define( 'ENQUEUES_CACHE_ENABLED', true );

// Set cache TTL in seconds (default: 12 hours)
define( 'ENQUEUES_CACHE_TTL', 12 * HOUR_IN_SECONDS );
```
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Documentation shows a different default TTL than the code.

The example comment says // Set cache TTL in seconds (default: 12 hours), but get_cache_ttl() in src/php/Function/Cache.php defaults to DAY_IN_SECONDS (24 hours). This will confuse users relying on the docs.

✏️ Suggested fix
-// Set cache TTL in seconds (default: 12 hours)
-define( 'ENQUEUES_CACHE_TTL', 12 * HOUR_IN_SECONDS );
+// Set cache TTL in seconds (default: 24 hours)
+define( 'ENQUEUES_CACHE_TTL', DAY_IN_SECONDS );
🤖 Prompt for AI Agents
In `@docs/THEME-ASSETS.md` around lines 140 - 146, The docs show
ENQUEUES_CACHE_TTL default as 12 hours but get_cache_ttl() in
src/php/Function/Cache.php uses DAY_IN_SECONDS (24 hours); update the
documentation in docs/THEME-ASSETS.md so the comment and example match the code
(change the comment to "default: 24 hours" and adjust the example TTL expression
to 24 * HOUR_IN_SECONDS or DAY_IN_SECONDS) so ENQUEUES_CACHE_TTL and
get_cache_ttl() are consistent.

Comment on lines 242 to 253
// Fallback logic: attempt to load fallback file.
if ( empty( $compiled_file_path ) && $fallback_file_name ) {
$compiled_file_path = asset_find_file_path( "{$dist_directory_part}/{$directory_part}", $fallback_file_name, $file_ext, $directory );
}
if ( ! empty( $fallback_compiled_file_path ) ) {
$full_file_path = "{$directory}{$fallback_compiled_file_path}";
$file_mtime = file_exists( $full_file_path ) ? filemtime( $full_file_path ) : 0;
$is_minified = false !== strpos( $fallback_compiled_file_path, '.min.' );

if ( ! empty( $compiled_file_path ) ) {
$data = [
$data = [
'handle' => sanitize_key( $fallback_file_name ),
'url' => esc_url( "{$directory_uri}{$compiled_file_path}" ),
'file' => esc_url( "{$directory}{$compiled_file_path}" ),
'ver' => filemtime( "{$directory}{$compiled_file_path}" ),
'minified' => false !== strpos( $compiled_file_path, '.min.' ),
'url' => esc_url( "{$directory_uri}{$fallback_compiled_file_path}" ),
'file' => esc_url( "{$directory}{$fallback_compiled_file_path}" ),
'minified' => $is_minified,
];
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Indentation anomaly — the fallback if block has an extra leading tab.

Line 243 has inconsistent indentation compared to the rest of the function (compare with line 207). This looks like a merge artifact. While PHP ignores whitespace, it harms readability and may confuse contributors.

✏️ Suggested fix
 	// Fallback logic: attempt to load fallback file.
-		if ( ! empty( $fallback_compiled_file_path ) ) {
+	if ( ! empty( $fallback_compiled_file_path ) ) {
 		$full_file_path = "{$directory}{$fallback_compiled_file_path}";
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Fallback logic: attempt to load fallback file.
if ( empty( $compiled_file_path ) && $fallback_file_name ) {
$compiled_file_path = asset_find_file_path( "{$dist_directory_part}/{$directory_part}", $fallback_file_name, $file_ext, $directory );
}
if ( ! empty( $fallback_compiled_file_path ) ) {
$full_file_path = "{$directory}{$fallback_compiled_file_path}";
$file_mtime = file_exists( $full_file_path ) ? filemtime( $full_file_path ) : 0;
$is_minified = false !== strpos( $fallback_compiled_file_path, '.min.' );
if ( ! empty( $compiled_file_path ) ) {
$data = [
$data = [
'handle' => sanitize_key( $fallback_file_name ),
'url' => esc_url( "{$directory_uri}{$compiled_file_path}" ),
'file' => esc_url( "{$directory}{$compiled_file_path}" ),
'ver' => filemtime( "{$directory}{$compiled_file_path}" ),
'minified' => false !== strpos( $compiled_file_path, '.min.' ),
'url' => esc_url( "{$directory_uri}{$fallback_compiled_file_path}" ),
'file' => esc_url( "{$directory}{$fallback_compiled_file_path}" ),
'minified' => $is_minified,
];
// Fallback logic: attempt to load fallback file.
if ( ! empty( $fallback_compiled_file_path ) ) {
$full_file_path = "{$directory}{$fallback_compiled_file_path}";
$file_mtime = file_exists( $full_file_path ) ? filemtime( $full_file_path ) : 0;
$is_minified = false !== strpos( $fallback_compiled_file_path, '.min.' );
$data = [
'handle' => sanitize_key( $fallback_file_name ),
'url' => esc_url( "{$directory_uri}{$fallback_compiled_file_path}" ),
'file' => esc_url( "{$directory}{$fallback_compiled_file_path}" ),
'minified' => $is_minified,
];
🤖 Prompt for AI Agents
In `@src/php/Function/Assets.php` around lines 242 - 253, The fallback if-block in
Assets.php has an extra leading tab causing inconsistent indentation; locate the
block that checks if ( ! empty( $fallback_compiled_file_path ) ) (referenced by
variables $fallback_compiled_file_path, $full_file_path, $file_mtime,
$is_minified and the $data array) and normalize its indentation to match the
surrounding function (align the if, its opening brace, inner lines and closing
brace with the rest of the function) so the block’s whitespace matches other
blocks and removes the merge-artifact tab.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant