Feature: Unit Blocks – merge into 2.1-trunk#815
Conversation
…ment in Best Time to Visit block
…mproved flexibility
…prefix handling for itinerary fields
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. Warning
|
| Cohort / File(s) | Summary |
|---|---|
Asset version updates build/blocks/best-time-to-visit/index.asset.php, build/paragraph-prefix.asset.php, build/blocks/destination-to-tour/index.asset.php |
Updated generated asset version hashes (no dependency or structural changes). |
Paragraph prefix activation (editor) src/js/blocks/paragraph-prefix.js, build/paragraph-prefix.js, build/blocks/best-time-to-visit/index.js, src/blocks/best-time-to-visit/index.js |
Broadened the condition enabling paragraph-prefix controls to also match itinerary-related classes (itinerary-accommodation, itinerary-location, itinerary-type, itinerary-drinks, itinerary-room). Minor example layout alignment tweak for best-time-to-visit. |
Itinerary pattern template patterns/itinerary-list.php |
Replaced itinerary pattern content with full-width layout, new wrapper classes (lsx-itinerary-info, itin-*-wrapper), consolidated field rows and placeholder content, and updated metadata names. |
Bindings and prefix logic (PHP) includes/classes/blocks/class-bindings.php |
Added maybe_get_prefix( $key, $build ) and updated build_itinerary_field() to prepend per-field prefixes (location, accommodation, type, drinks, room). render_itinerary_block() now uses a dedicated build template per item. |
Query loop / related-item keys includes/classes/blocks/class-query-loop.php, src/blocks/destination-to-tour/index.js, build/blocks/destination-to-tour/index.js |
Replaced some custom-field queries with get_post_meta() lookups; introduced lsx_to_related_connection_query_key filter to determine meta-key for related items. Also added parents: true to paragraph binding in destination-to-tour variation. |
Changelog changelog.md |
Added "Unit Blocks" entry to 2.1.0 "Added" section. |
Estimated code review effort
🎯 3 (Moderate) | ⏱️ ~25 minutes
- Pay special attention to:
includes/classes/blocks/class-bindings.php(prefix extraction regex and HTML parsing edge-cases),patterns/itinerary-list.php(template/content correctness and markup classes), andincludes/classes/blocks/class-query-loop.php(filter fallback and meta-key handling).
Possibly related PRs
- Enhancement: Single-Line Fast-Facts Meta Display Implementation #802 — Related work around paragraph-prefix, prefix/prefixBold changes and rendering hooks.
- Updating the changelog with recent PR Information #767 — Changelog adjustments and 2.1.0 entry edits that overlap with this PR’s changelog change.
- Refactor dynamic blocks: enhance metadata and i18n support for accommodation/destination/tour blocks #766 — Past refactor touching destination-to-tour and block variation registration areas (related to adding
parents: true).
Suggested labels
comp:block-variations, comp:block-editor, comp:block-json
Suggested reviewers
- tibiii
Poem
🐰 I nibble prefixes from paragraph nests,
I tuck them neat in itinerary vests,
Patterns hop wider, classes align,
Build hashes refreshed — everything fine,
A rabbit’s cheer for tidy block quests!
Pre-merge checks and finishing touches
✅ Passed checks (3 passed)
| Check name | Status | Explanation |
|---|---|---|
| Description Check | ✅ Passed | Check skipped - CodeRabbit’s high-level summary is enabled. |
| Title check | ✅ Passed | The title 'Feature: Unit Blocks – merge into 2.1-trunk' directly describes the main purpose of the PR, which is to merge unit blocks feature into the 2.1-trunk release branch. |
| Docstring Coverage | ✅ Passed | Docstring coverage is 80.00% which is sufficient. The required threshold is 80.00%. |
✨ Finishing touches
- 📝 Generate docstrings
🧪 Generate unit tests (beta)
- Create PR with unit tests
- Post copyable unit tests in a comment
- Commit unit tests in branch
feature/unit-blocks
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.
Comment @coderabbitai help to get the list of available commands and usage tips.
Summary of ChangesHello @krugazul, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request integrates the Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Actionable comments posted: 6
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/js/blocks/paragraph-prefix.js (1)
137-143: Critical: Undeclared variablestyleElcreates implicit global.
styleElis used without being declared withletorconst, which creates an implicit global variable. This is a bug that will cause issues in strict mode and pollutes the global namespace.let existingStyle = targetDoc.getElementById( uniqueId ); if ( ! existingStyle ) { - styleEl = targetDoc.createElement( 'style' ); + const styleEl = targetDoc.createElement( 'style' ); styleEl.id = uniqueId; targetDoc.head.appendChild( styleEl ); + styleEl.textContent = css; + } else { + existingStyle.textContent = css; } - styleEl.textContent = css;The current code also has a logic issue: when
existingStyleis found,styleElremains undefined, yetstyleEl.textContent = cssis called outside theifblock.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (9)
build/blocks/best-time-to-visit/index.asset.php(1 hunks)build/blocks/best-time-to-visit/index.js(1 hunks)build/paragraph-prefix.asset.php(1 hunks)build/paragraph-prefix.js(1 hunks)includes/classes/blocks/class-bindings.php(5 hunks)includes/classes/blocks/class-query-loop.php(2 hunks)patterns/itinerary-list.php(2 hunks)src/blocks/best-time-to-visit/index.js(1 hunks)src/js/blocks/paragraph-prefix.js(1 hunks)
🧰 Additional context used
📓 Path-based instructions (18)
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Use semicolons to terminate statements in JavaScript block code
Ensure all generated code follows ESLint rules and WordPress Coding Standards before deployment
Files:
build/blocks/best-time-to-visit/index.jsbuild/paragraph-prefix.jssrc/blocks/best-time-to-visit/index.jssrc/js/blocks/paragraph-prefix.js
**/*.{php,js,jsx,ts,tsx,json}
📄 CodeRabbit inference engine (GEMINI.md)
Follow WordPress Coding Standards including proper namespacing, security practices (sanitization/escaping), and code organization
Files:
build/blocks/best-time-to-visit/index.jsbuild/paragraph-prefix.jssrc/blocks/best-time-to-visit/index.jsincludes/classes/blocks/class-query-loop.phppatterns/itinerary-list.phpbuild/blocks/best-time-to-visit/index.asset.phpbuild/paragraph-prefix.asset.phpsrc/js/blocks/paragraph-prefix.jsincludes/classes/blocks/class-bindings.php
**/*.{js,jsx,ts,tsx,php}
📄 CodeRabbit inference engine (GEMINI.md)
Implement accessibility features following WCAG 2.2 AA standards in all block components and patterns
Files:
build/blocks/best-time-to-visit/index.jsbuild/paragraph-prefix.jssrc/blocks/best-time-to-visit/index.jsincludes/classes/blocks/class-query-loop.phppatterns/itinerary-list.phpbuild/blocks/best-time-to-visit/index.asset.phpbuild/paragraph-prefix.asset.phpsrc/js/blocks/paragraph-prefix.jsincludes/classes/blocks/class-bindings.php
**/*.{php,js,jsx,ts,tsx}
📄 CodeRabbit inference engine (GEMINI.md)
Validate generated code against WordPress standards, test thoroughly, check security implications, and review for proper sanitization/escaping
Files:
build/blocks/best-time-to-visit/index.jsbuild/paragraph-prefix.jssrc/blocks/best-time-to-visit/index.jsincludes/classes/blocks/class-query-loop.phppatterns/itinerary-list.phpbuild/blocks/best-time-to-visit/index.asset.phpbuild/paragraph-prefix.asset.phpsrc/js/blocks/paragraph-prefix.jsincludes/classes/blocks/class-bindings.php
**/*.{js,jsx,ts,tsx,php,scss,css}
📄 CodeRabbit inference engine (GEMINI.md)
Use camelCase for variable and function names, kebab-case for CSS classes, and snake_case for PHP variable names per WordPress Coding Standards
Files:
build/blocks/best-time-to-visit/index.jsbuild/paragraph-prefix.jssrc/blocks/best-time-to-visit/index.jsincludes/classes/blocks/class-query-loop.phppatterns/itinerary-list.phpbuild/blocks/best-time-to-visit/index.asset.phpbuild/paragraph-prefix.asset.phpsrc/js/blocks/paragraph-prefix.jsincludes/classes/blocks/class-bindings.php
**/*.{js,jsx,ts,tsx,scss,css}
📄 CodeRabbit inference engine (GEMINI.md)
For performance optimization, implement code splitting, lazy loading, and minimize CSS/JavaScript bundle sizes in block components
Files:
build/blocks/best-time-to-visit/index.jsbuild/paragraph-prefix.jssrc/blocks/best-time-to-visit/index.jssrc/js/blocks/paragraph-prefix.js
**/*.{js,ts,tsx,jsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.{js,ts,tsx,jsx}: Use async/await syntax; avoid .then() chains
Use named exports; avoid default exports unless wrapping a module
Files:
build/blocks/best-time-to-visit/index.jsbuild/paragraph-prefix.jssrc/blocks/best-time-to-visit/index.jssrc/js/blocks/paragraph-prefix.js
src/blocks/**/*.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use Block API v3 standards when developing blocks
Files:
src/blocks/best-time-to-visit/index.js
{src/blocks/**/*.{js,jsx,ts,tsx},src/**/*.php,inc/**/*.php}
📄 CodeRabbit inference engine (AGENTS.md)
Apply WCAG 2.2 AA accessibility standards to all blocks and UI components
Files:
src/blocks/best-time-to-visit/index.js
src/**/*.{js,ts,tsx,jsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/**/*.{js,ts,tsx,jsx}: Document public functions with JSDoc
Do not include any WordPress-related imports, functions, or file structures
Do not reference or assume plugins like WooCommerce or Wetu
Files:
src/blocks/best-time-to-visit/index.jssrc/js/blocks/paragraph-prefix.js
**/blocks/**/*.php
📄 CodeRabbit inference engine (CLAUDE.md)
PHP render callbacks must be properly documented with descriptions of attributes and return values
Files:
includes/classes/blocks/class-query-loop.phpbuild/blocks/best-time-to-visit/index.asset.phpincludes/classes/blocks/class-bindings.php
**/*query*loop*.{php,js,jsx,ts,tsx}
📄 CodeRabbit inference engine (GEMINI.md)
Implement filter and search functionality in query-loop patterns with proper WP_Query parameter handling and caching strategies
Files:
includes/classes/blocks/class-query-loop.php
**/*.php
📄 CodeRabbit inference engine (AGENTS.md)
Follow WordPress Coding Standards (WPCS) for all WordPress code
**/*.php: Store block patterns in the/patterns/directory at the root of the plugin (WordPress standard for plugins), not in/includes/patterns/
Use text domain 'tour-operator' for all localization strings in the plugin
Files:
includes/classes/blocks/class-query-loop.phppatterns/itinerary-list.phpbuild/blocks/best-time-to-visit/index.asset.phpbuild/paragraph-prefix.asset.phpincludes/classes/blocks/class-bindings.php
**/*.{php,html}
📄 CodeRabbit inference engine (.github/instructions/patterns-templates-refactoring.instructions.md)
**/*.{php,html}: Always useLSX_TO_URLandLSX_TO_PATHconstants for asset paths in plugin files
Include CSS variable fallbacks with absolute hex values in inline styles for plugin compatibility with any theme
Use CSS variable formatvar(--wp--preset--[type]--[name], fallback_value)in inline styles, notvar:preset|[type]|[name]format
Usevar:preset|[type]|[name]format only within JSON block attributes, not in inline styles
Use the correct spacing preset names: 'tiny' (10px), 'small' (16px), 'medium' (32px), 'large' (48px), and 'x-small' (8px)
Files:
includes/classes/blocks/class-query-loop.phppatterns/itinerary-list.phpbuild/blocks/best-time-to-visit/index.asset.phpbuild/paragraph-prefix.asset.phpincludes/classes/blocks/class-bindings.php
**/*.{php,twig}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Do not generate .php, .twig, or legacy CMS files
Files:
includes/classes/blocks/class-query-loop.phppatterns/itinerary-list.phpbuild/blocks/best-time-to-visit/index.asset.phpbuild/paragraph-prefix.asset.phpincludes/classes/blocks/class-bindings.php
**/patterns/*.php
📄 CodeRabbit inference engine (.github/instructions/figma-to-wordpress-pattern-extraction.instructions.md)
**/patterns/*.php: WordPress pattern PHP files must be located in /patterns/[pattern-slug].php at root level with required metadata in PHP DocBlock
Use plugin constants like LSX_TO_URL for asset paths in pattern files, not theme functions like get_template_directory_uri()
Always use 'tour-operator' as the text domain for internationalization functions in WordPress pattern files
Wrap all user-facing text in internationalization functions (esc_html_e(), (), esc_attr()) in WordPress pattern files
Preserve Figma layer names in WordPress blocks using the metadata attribute with 'name' property
Use block binding source 'lsx/post-meta' for custom data connections in WordPress block patterns
Use self-closing block syntax for dynamic/static blocks (e.g., lsx-tour-operator/icons, post-featured-image) that render via PHP
Do not embed SVG markup directly in icon block patterns; use self-closing icon block syntax to allow dynamic rendering
Include absolute fallback values (hex colors, rem sizes) for all CSS variables in inline styles within WordPress patterns
Use WordPress preset slug format in JSON block attributes (var:preset|color|slug format) separately from inline CSS fallback syntax
Add PHP DocBlock metadata with title, slug (tour-operator/pattern-name format), description, categories, keywords, block types, and post types to WordPress pattern files
Use LSX_TO_URL constant to reference plugin assets instead of theme asset functions in pattern content strings
Include the phpcs:ignoreFile comment for PluginCheck.CodeAnalysis.ImageFunctions.NonEnqueuedImage at the top of WordPress pattern PHP files
Use available icon block attributes (iconType: 'outline'|'solid', iconName from icon library) in lsx-tour-operator/icons blocks within patterns
**/patterns/*.php: Use PHP array return format for plugin patterns instead of file header comments (unlike themes where patterns auto-register from/patterns/using file headers)
Include required pattern properties: 'title' and e...
Files:
patterns/itinerary-list.php
**/{patterns,templates,parts}/*.{php,html}
📄 CodeRabbit inference engine (.github/instructions/patterns-templates-refactoring.instructions.md)
**/{patterns,templates,parts}/*.{php,html}: For icon blocks, use self-closing syntax and never embed HTML content inside icon block markup to prevent validation errors
Use primary color preset for buttons, borders, and main brand elements; use 'contrast' preset for text/links; use 'base' for white backgrounds
Files:
patterns/itinerary-list.php
**/{templates,patterns,parts}/*.{php,html}
📄 CodeRabbit inference engine (.github/instructions/patterns-templates-refactoring.instructions.md)
Use wide alignment constraint for main content containers in single templates and align-full for full-width sections like breadcrumbs
Files:
patterns/itinerary-list.php
🧬 Code graph analysis (2)
build/paragraph-prefix.js (1)
build/blocks/best-time-to-visit/index.js (4)
e(1-1)t(1-1)a(1-1)i(1-1)
includes/classes/blocks/class-bindings.php (2)
includes/functions.php (5)
lsx_to_has_itinerary(38-52)lsx_to_itinerary_loop(62-70)lsx_to_itinerary_loop_item(80-86)lsx_to_itinerary_accommodation(349-351)lsx_to_itinerary_accommodation_type(361-363)includes/template-tags/general.php (2)
lsx_to_itinerary_drinks_basis(90-103)lsx_to_itinerary_room_basis(53-66)
🪛 PHPMD (2.15.0)
includes/classes/blocks/class-query-loop.php
528-528: The variable $found_items is not named in camelCase. (undefined)
(CamelCaseVariableName)
includes/classes/blocks/class-bindings.php
311-311: The variable $build_template is not named in camelCase. (undefined)
(CamelCaseVariableName)
319-319: The variable $itinerary_count is not named in camelCase. (undefined)
(CamelCaseVariableName)
420-423: The method build_itinerary_field uses an else expression. Else clauses are basically not necessary and you can simplify the code by not using them. (undefined)
(ElseExpression)
431-437: The method maybe_get_prefix is not named in camelCase. (undefined)
(CamelCaseMethodName)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Summary
🔇 Additional comments (14)
build/paragraph-prefix.asset.php (1)
1-1: LGTM!Standard auto-generated asset file with updated version hash reflecting the source changes.
build/blocks/best-time-to-visit/index.js (1)
1-1: LGTM!Minified build output corresponding to the source file. Logic verification is performed on the source file.
src/blocks/best-time-to-visit/index.js (2)
45-49: Verify alignment consistency between inner blocks.The parent wrapper (line 38) and example (line 103) use
verticalAlignment: 'top', but this inner group still usesverticalAlignment: 'middle'. If the change to'top'was intentional for consistent visual appearance, consider updating this inner group as well.{ layout: { type: 'flex', flexWrap: 'nowrap', - verticalAlignment: 'middle', + verticalAlignment: 'top', }, },
103-103: LGTM!Vertical alignment change to
'top'in the example block aligns with the parent wrapper's layout setting.build/blocks/best-time-to-visit/index.asset.php (1)
1-1: LGTM!Standard auto-generated asset file with correct
wp-i18ndependency.includes/classes/blocks/class-query-loop.php (1)
178-179: LGTM!Direct use of
get_post_metafor raw value retrieval is cleaner and more efficient than the previous approach.build/paragraph-prefix.js (1)
1-1: Build reflects source file issues.This minified build contains the undeclared
styleElvariable bug identified insrc/js/blocks/paragraph-prefix.js. Once the source file is fixed, this will need to be rebuilt.includes/classes/blocks/class-bindings.php (3)
420-423: Logic is correct; else block is appropriate here.The static analysis hint suggests avoiding else expressions, but in this context, the else block clearly separates the two mutually exclusive outcomes (hide element vs. prepend prefix). The current structure is readable and appropriate.
370-398: Prefix handling for itinerary fields looks good.The addition of prefix extraction for location, accommodation, type, drinks, and room fields follows a consistent pattern and integrates well with the existing field-building logic.
318-336: Itinerary rendering refactor using build template is well-structured.The change to use
$build_templateas a dedicated template for each itinerary item iteration is a cleaner approach than mutating the original block content directly. The implementation correctly preserves the template and aggregates results.patterns/itinerary-list.php (4)
59-60: "Card Link" placeholder coordinates with PHP rendering logic.The placeholder text "Card Link" in the paragraph blocks is intentionally replaced by the
maybe_get_prefixmethod inclass-bindings.php. This coupling works but could benefit from a code comment explaining the relationship for future maintainers.Consider adding a comment near the pattern content explaining the placeholder:
// Note: "Card Link" is a placeholder that gets replaced during render by class-bindings.php::maybe_get_prefix()Also applies to: 67-68, 75-76, 83-84, 91-92
16-23: Pattern metadata is properly configured.The pattern array includes all required properties: title, description, categories, keywords, and inserter setting. The
inserter=> false is appropriate for patterns intended for programmatic insertion only.
57-94: Itinerary information rows are well-structured.The wrapper groups (
itin-location-wrapper,itin-accommodation-wrapper, etc.) provide proper hooks for the PHP rendering logic to hide empty fields. The use of self-closing icon block syntax and prefix attributes follows the coding guidelines.
24-25: Full-width alignment correctly implemented.The columns block now uses
align="full"attribute andalignfullclass, which is appropriate for full-width sections per the coding guidelines.
| $build_template = $block_content; | ||
| $group = array(); | ||
|
|
||
| //$pattern_registry = \WP_Block_Patterns_Registry::get_instance(); | ||
| //$pattern_registry->get_registered(); |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Remove commented-out code or explain its purpose.
The commented-out pattern registry code on lines 314-315 appears to be dead code. If it's no longer needed, remove it to maintain code cleanliness. If it's intended for future use, add a TODO comment explaining the intent.
$build_template = $block_content;
$group = array();
- //$pattern_registry = \WP_Block_Patterns_Registry::get_instance();
- //$pattern_registry->get_registered();
-
// Iterate through and build our itinerary from the block content template.📝 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.
| $build_template = $block_content; | |
| $group = array(); | |
| //$pattern_registry = \WP_Block_Patterns_Registry::get_instance(); | |
| //$pattern_registry->get_registered(); | |
| $build_template = $block_content; | |
| $group = array(); | |
| // Iterate through and build our itinerary from the block content template. |
🧰 Tools
🪛 PHPMD (2.15.0)
311-311: The variable $build_template is not named in camelCase. (undefined)
(CamelCaseVariableName)
🤖 Prompt for AI Agents
In includes/classes/blocks/class-bindings.php around lines 311 to 315, there is
commented-out code referencing the WP_Block_Patterns_Registry; remove these two
commented lines if they are not needed to eliminate dead code and keep the file
clean, or if they are intentionally left for future use, replace the commented
lines with a single TODO comment that explains why the registry code is
preserved and when/how it should be re-enabled.
| public function maybe_get_prefix( $key, $build ) { | ||
| $pattern = '/<p\s+[^>]*\bclass="[^"]*\b' . esc_attr( $key ) . '\b[^"]*"[^>]*>(.*?)<\/p>/is'; | ||
| if ( preg_match( $pattern, $build, $matches ) ) { | ||
| return str_replace( 'Card Link', '', $matches[1] ); | ||
| } | ||
| return ''; | ||
| } |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major
Add PHPDoc documentation for the new method.
Per coding guidelines, PHP render callbacks and methods must be properly documented with descriptions of attributes and return values. The maybe_get_prefix method is missing its PHPDoc block.
+ /**
+ * Extracts the prefix text from a block's HTML content based on a CSS class key.
+ *
+ * Searches for a paragraph element with the specified class and returns its
+ * inner content with placeholder text removed.
+ *
+ * @param string $key The CSS class identifier to search for (e.g., 'itinerary-location').
+ * @param string $build The HTML content to search within.
+ * @return string The extracted prefix text, or empty string if not found.
+ */
public function maybe_get_prefix( $key, $build ) {
$pattern = '/<p\s+[^>]*\bclass="[^"]*\b' . esc_attr( $key ) . '\b[^"]*"[^>]*>(.*?)<\/p>/is';
if ( preg_match( $pattern, $build, $matches ) ) {
return str_replace( 'Card Link', '', $matches[1] );
}
return '';
}🧰 Tools
🪛 PHPMD (2.15.0)
431-437: The method maybe_get_prefix is not named in camelCase. (undefined)
(CamelCaseMethodName)
🤖 Prompt for AI Agents
In includes/classes/blocks/class-bindings.php around lines 431 to 437, the new
method maybe_get_prefix is missing PHPDoc; add a PHPDoc block immediately above
the method that briefly describes what the method does, documents the parameters
($key string The CSS class/key to search for, $build string The HTML block
content to search), specifies the return value (string The extracted prefix or
an empty string), and includes any relevant tags such as @since and @return (and
@param for each parameter) consistent with existing project doc style.
| $pattern = '/<p\s+[^>]*\bclass="[^"]*\b' . esc_attr( $key ) . '\b[^"]*"[^>]*>(.*?)<\/p>/is'; | ||
| if ( preg_match( $pattern, $build, $matches ) ) { | ||
| return str_replace( 'Card Link', '', $matches[1] ); |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Hardcoded placeholder string creates tight coupling.
The hardcoded 'Card Link' string creates implicit coupling between this PHP method and the pattern template. Consider extracting this as a class constant or making it configurable to improve maintainability and make the relationship explicit.
+ /**
+ * Placeholder text used in itinerary patterns that gets replaced with actual content.
+ *
+ * @var string
+ */
+ const ITINERARY_PLACEHOLDER = 'Card Link';
+
public function maybe_get_prefix( $key, $build ) {
$pattern = '/<p\s+[^>]*\bclass="[^"]*\b' . esc_attr( $key ) . '\b[^"]*"[^>]*>(.*?)<\/p>/is';
if ( preg_match( $pattern, $build, $matches ) ) {
- return str_replace( 'Card Link', '', $matches[1] );
+ return str_replace( self::ITINERARY_PLACEHOLDER, '', $matches[1] );
}
return '';
}📝 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.
| $pattern = '/<p\s+[^>]*\bclass="[^"]*\b' . esc_attr( $key ) . '\b[^"]*"[^>]*>(.*?)<\/p>/is'; | |
| if ( preg_match( $pattern, $build, $matches ) ) { | |
| return str_replace( 'Card Link', '', $matches[1] ); | |
| /** | |
| * Placeholder text used in itinerary patterns that gets replaced with actual content. | |
| * | |
| * @var string | |
| */ | |
| const ITINERARY_PLACEHOLDER = 'Card Link'; | |
| public function maybe_get_prefix( $key, $build ) { | |
| $pattern = '/<p\s+[^>]*\bclass="[^"]*\b' . esc_attr( $key ) . '\b[^"]*"[^>]*>(.*?)<\/p>/is'; | |
| if ( preg_match( $pattern, $build, $matches ) ) { | |
| return str_replace( self::ITINERARY_PLACEHOLDER, '', $matches[1] ); | |
| } | |
| return ''; | |
| } |
🤖 Prompt for AI Agents
In includes/classes/blocks/class-bindings.php around lines 432 to 434, the
method currently uses the hardcoded string 'Card Link' when stripping the
matched content which couples the code to the template; replace the literal with
a named class constant (e.g. CARD_LINK_PLACEHOLDER) or a configurable
property/filter and use that constant/property in the str_replace call so the
placeholder is explicit and maintainable, add the constant to the class (or
accept/configure via constructor or apply_filters) and update any tests/usages
to reference the new constant/property.
| /** | ||
| * lsx_to_related_connection_found_items filter. | ||
| * @var $key | ||
| * @var $current_item_ID | ||
| */ | ||
| $key = apply_filters( 'lsx_to_related_connection_query_key', $to . '_to_' . $from, get_the_ID() ); | ||
| $found_items = get_post_meta( get_the_ID(), $key, true ); |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Consider improving the filter documentation.
The filter introduction is a good refactor for flexibility. However, the docblock format could be improved to follow WordPress documentation standards for filters:
- /**
- * lsx_to_related_connection_found_items filter.
- * @var $key
- * @var $current_item_ID
- */
- $key = apply_filters( 'lsx_to_related_connection_query_key', $to . '_to_' . $from, get_the_ID() );
+ /**
+ * Filters the post meta key used to retrieve related connection items.
+ *
+ * @since 2.1.0
+ *
+ * @param string $key The default meta key (e.g., 'tour_to_accommodation').
+ * @param int $post_id The current post ID.
+ * @return string The filtered meta key.
+ */
+ $key = apply_filters( 'lsx_to_related_connection_query_key', $to . '_to_' . $from, get_the_ID() );Note: The PHPMD warning about $found_items naming is a false positive — WordPress PHP coding standards use snake_case for variable names.
📝 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.
| /** | |
| * lsx_to_related_connection_found_items filter. | |
| * @var $key | |
| * @var $current_item_ID | |
| */ | |
| $key = apply_filters( 'lsx_to_related_connection_query_key', $to . '_to_' . $from, get_the_ID() ); | |
| $found_items = get_post_meta( get_the_ID(), $key, true ); | |
| /** | |
| * Filters the post meta key used to retrieve related connection items. | |
| * | |
| * @since 2.1.0 | |
| * | |
| * @param string $key The default meta key (e.g., 'tour_to_accommodation'). | |
| * @param int $post_id The current post ID. | |
| * @return string The filtered meta key. | |
| */ | |
| $key = apply_filters( 'lsx_to_related_connection_query_key', $to . '_to_' . $from, get_the_ID() ); | |
| $found_items = get_post_meta( get_the_ID(), $key, true ); |
🧰 Tools
🪛 PHPMD (2.15.0)
528-528: The variable $found_items is not named in camelCase. (undefined)
(CamelCaseVariableName)
| <div class="wp-block-group lsx-itinerary-info has-base-background-color has-background" style="border-radius:0.5rem;padding-top:var(--wp--preset--spacing--30);padding-right:var(--wp--preset--spacing--30);padding-bottom:var(--wp--preset--spacing--30);padding-left:var(--wp--preset--spacing--30)"><!-- wp:group {"metadata":{"name":"' . esc_attr__( 'Location Row', 'tour-operator' ) . '"},"className":"itin-location-wrapper","style":{"spacing":{"blockGap":"0.3125rem"}},"layout":{"type":"flex","flexWrap":"wrap","verticalAlignment":"center"}} --> | ||
| <div class="wp-block-group itin-location-wrapper"><!-- wp:group {"style":{"spacing":{"blockGap":"0.3125rem"}},"layout":{"type":"flex","flexWrap":"nowrap","verticalAlignment":"center"}} --> | ||
| <div class="wp-block-group"><!-- wp:lsx-tour-operator/icons {"iconType":"solid","iconName":"destinationIcon"} /--> | ||
| <div class="wp-block-group lsx-itinerary-info has-base-background-color has-background" style="border-radius:0.5rem;padding-top:var(--wp--preset--spacing--30);padding-right:var(--wp--preset--spacing--30);padding-bottom:var(--wp--preset--spacing--30);padding-left:var(--wp--preset--spacing--30)"> |
There was a problem hiding this comment.
Add absolute fallback values for CSS variables in inline styles.
Per coding guidelines, inline styles must include CSS variable fallbacks with absolute hex/rem values for plugin compatibility with any theme. The spacing variables should have fallback values.
For example, line 54 should include fallbacks:
-<div class="wp-block-group lsx-itinerary-info has-base-background-color has-background" style="border-radius:0.5rem;padding-top:var(--wp--preset--spacing--30);padding-right:var(--wp--preset--spacing--30);padding-bottom:var(--wp--preset--spacing--30);padding-left:var(--wp--preset--spacing--30)">
+<div class="wp-block-group lsx-itinerary-info has-base-background-color has-background" style="border-radius:0.5rem;padding-top:var(--wp--preset--spacing--30, 1.5rem);padding-right:var(--wp--preset--spacing--30, 1.5rem);padding-bottom:var(--wp--preset--spacing--30, 1.5rem);padding-left:var(--wp--preset--spacing--30, 1.5rem)">This applies to other inline styles throughout the pattern as well (lines 35, 41, etc.).
📝 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.
| <div class="wp-block-group lsx-itinerary-info has-base-background-color has-background" style="border-radius:0.5rem;padding-top:var(--wp--preset--spacing--30);padding-right:var(--wp--preset--spacing--30);padding-bottom:var(--wp--preset--spacing--30);padding-left:var(--wp--preset--spacing--30)"> | |
| <div class="wp-block-group lsx-itinerary-info has-base-background-color has-background" style="border-radius:0.5rem;padding-top:var(--wp--preset--spacing--30, 1.5rem);padding-right:var(--wp--preset--spacing--30, 1.5rem);padding-bottom:var(--wp--preset--spacing--30, 1.5rem);padding-left:var(--wp--preset--spacing--30, 1.5rem)"> |
🤖 Prompt for AI Agents
In patterns/itinerary-list.php around line 54 (and similarly update lines 35,
41, etc.), the inline style uses CSS variables without absolute fallbacks;
update each var(...) to include a concrete fallback value (e.g. spacing vars use
a rem fallback like var(--wp--preset--spacing--30, 1.875rem) and color vars use
a hex fallback like var(--wp--preset--color--base-background, #ffffff)),
applying the corresponding rem/hex fallbacks for every spacing and color
variable in the inline style attributes so the block works even when theme
variables are unavailable.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| public function maybe_get_prefix( $key, $build ) { | ||
| $pattern = '/<p\s+[^>]*\bclass="[^"]*\b' . esc_attr( $key ) . '\b[^"]*"[^>]*>(.*?)<\/p>/is'; | ||
| if ( preg_match( $pattern, $build, $matches ) ) { | ||
| return str_replace( 'Card Link', '', $matches[1] ); | ||
| } |
There was a problem hiding this comment.
Preserve itinerary prefixes on frontend output
The new itinerary pattern now stores labels (e.g., “Location:”, “Accommodation:”, “Type:”) in the paragraph prefix attribute while the rendered HTML contains only the Card Link placeholder. maybe_get_prefix() still derives the prefix from the paragraph inner HTML and strips the placeholder (str_replace( 'Card Link', '', $matches[1] )), so it returns an empty string for all itinerary fields. When build_itinerary_field() then concatenates $prefix . $value, the frontend itinerary list renders values without any labels, while the prefix pseudo-element is applied only in the editor. Users viewing itineraries will no longer see which value corresponds to location, accommodation, type, drinks, or room.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Code Review
This pull request merges the feature/unit-blocks branch, introducing new unit block functionalities and refining existing ones. The changes align with WordPress coding standards. My review focuses on improving code clarity, maintainability, and addressing some internationalization regressions. I've pointed out areas with commented-out code, redundant conditions, and opportunities for refactoring to reduce code duplication. I've also highlighted incorrect PHPDoc and hardcoded strings that should be made translatable.
| <div class="wp-block-group lsx-itinerary-info has-base-background-color has-background" style="border-radius:0.5rem;padding-top:var(--wp--preset--spacing--30);padding-right:var(--wp--preset--spacing--30);padding-bottom:var(--wp--preset--spacing--30);padding-left:var(--wp--preset--spacing--30)"> | ||
|
|
||
| <!-- wp:paragraph {"style":{"typography":{"fontStyle":"normal","fontWeight":"700"}},"fontSize":"medium"} --> | ||
| <p class="has-medium-font-size" style="font-style:normal;font-weight:700">' . esc_html__( 'Location:', 'tour-operator' ) . '</p> | ||
| <!-- /wp:paragraph --></div> | ||
| <!-- /wp:group --> | ||
|
|
||
| <!-- wp:paragraph {"metadata":{"name":"' . esc_attr__( 'Location Value', 'tour-operator' ) . '"},"className":"itinerary-location","fontSize":"medium"} --> | ||
| <p class="itinerary-location has-medium-font-size">' . esc_html__( 'Location', 'tour-operator' ) . '</p> | ||
| <!-- wp:group {"metadata":{"name":"Location Row"},"className":"itin-location-wrapper","style":{"spacing":{"blockGap":"0.3125rem"}},"layout":{"type":"flex","flexWrap":"nowrap","verticalAlignment":"center"}} --> | ||
| <div class="wp-block-group itin-location-wrapper"><!-- wp:lsx-tour-operator/icons {"iconType":"solid","iconName":"destinationIcon"} /--> | ||
| <!-- wp:paragraph {"metadata":{"name":"Location Value"},"className":"itinerary-location","fontSize":"medium","prefix":"Location:","prefixBold":true} --> | ||
| <p class="itinerary-location has-medium-font-size">Card Link</p> | ||
| <!-- /wp:paragraph --></div> | ||
| <!-- /wp:group --> | ||
|
|
||
| <!-- wp:group {"metadata":{"name":"' . esc_attr__( 'Accommodation Row', 'tour-operator' ) . '"},"className":"itin-accommodation-wrapper","style":{"spacing":{"blockGap":"0.3125rem"}},"layout":{"type":"flex","flexWrap":"wrap","verticalAlignment":"center"}} --> | ||
| <div class="wp-block-group itin-accommodation-wrapper"><!-- wp:group {"style":{"spacing":{"blockGap":"0.3125rem"}},"layout":{"type":"flex","flexWrap":"nowrap","verticalAlignment":"center"}} --> | ||
| <div class="wp-block-group"><!-- wp:lsx-tour-operator/icons {"iconType":"solid","iconName":"accommodationIcon"} /--> | ||
|
|
||
| <!-- wp:paragraph {"style":{"typography":{"fontStyle":"normal","fontWeight":"700"}},"fontSize":"medium"} --> | ||
| <p class="has-medium-font-size" style="font-style:normal;font-weight:700">' . esc_html__( 'Accommodation:', 'tour-operator' ) . '</p> | ||
| <!-- /wp:paragraph --></div> | ||
| <!-- /wp:group --> | ||
|
|
||
| <!-- wp:paragraph {"metadata":{"name":"' . esc_attr__( 'Accommodation Value', 'tour-operator' ) . '"},"className":"itinerary-accommodation","fontSize":"medium"} --> | ||
| <p class="itinerary-accommodation has-medium-font-size">' . esc_html__( 'Card Link', 'tour-operator' ) . '</p> | ||
| <!-- wp:group {"metadata":{"name":"Accommodation Row"},"className":"itin-accommodation-wrapper","style":{"spacing":{"blockGap":"0.3125rem"}},"layout":{"type":"flex","flexWrap":"nowrap","verticalAlignment":"center"}} --> | ||
| <div class="wp-block-group itin-accommodation-wrapper"><!-- wp:lsx-tour-operator/icons {"iconType":"solid","iconName":"accommodationIcon"} /--> | ||
| <!-- wp:paragraph {"metadata":{"name":"Accommodation Value"},"className":"itinerary-accommodation","fontSize":"medium","prefix":"Accommodation:","prefixBold":true} --> | ||
| <p class="itinerary-accommodation has-medium-font-size">Card Link</p> | ||
| <!-- /wp:paragraph --></div> | ||
| <!-- /wp:group --> | ||
|
|
||
| <!-- wp:group {"metadata":{"name":"' . esc_attr__( 'Type Row', 'tour-operator' ) . '"},"className":"itin-type-wrapper","style":{"spacing":{"blockGap":"0.3125rem"}},"layout":{"type":"flex","flexWrap":"wrap","verticalAlignment":"center"}} --> | ||
| <div class="wp-block-group itin-type-wrapper"><!-- wp:group {"style":{"spacing":{"blockGap":"0.3125rem"}},"layout":{"type":"flex","flexWrap":"nowrap","verticalAlignment":"center"}} --> | ||
| <div class="wp-block-group"><!-- wp:lsx-tour-operator/icons {"iconType":"solid","iconName":"accommodationTypeIcon"} /--> | ||
|
|
||
| <!-- wp:paragraph {"style":{"typography":{"fontStyle":"normal","fontWeight":"700"}},"fontSize":"medium"} --> | ||
| <p class="has-medium-font-size" style="font-style:normal;font-weight:700">' . esc_html__( 'Type:', 'tour-operator' ) . '</p> | ||
| <!-- /wp:paragraph --></div> | ||
| <!-- /wp:group --> | ||
|
|
||
| <!-- wp:paragraph {"metadata":{"name":"' . esc_attr__( 'Type Value', 'tour-operator' ) . '"},"className":"itinerary-type","fontSize":"medium"} --> | ||
| <p class="itinerary-type has-medium-font-size">' . esc_html__( 'Card Link', 'tour-operator' ) . '</p> | ||
| <!-- wp:group {"metadata":{"name":"Type Row"},"className":"itin-type-wrapper","style":{"spacing":{"blockGap":"0.3125rem"}},"layout":{"type":"flex","flexWrap":"nowrap","verticalAlignment":"top"}} --> | ||
| <div class="wp-block-group itin-type-wrapper"><!-- wp:lsx-tour-operator/icons {"iconType":"solid","iconName":"accommodationTypeIcon"} /--> | ||
| <!-- wp:paragraph {"metadata":{"name":"Type Value"},"className":"itinerary-type","fontSize":"medium","prefix":"Type:","prefixBold":true} --> | ||
| <p class="itinerary-type has-medium-font-size">Card Link</p> | ||
| <!-- /wp:paragraph --></div> | ||
| <!-- /wp:group --> | ||
|
|
||
| <!-- wp:group {"metadata":{"name":"' . esc_attr__( 'Drinks Basis Row', 'tour-operator' ) . '"},"className":"itin-drinks-wrapper","style":{"spacing":{"blockGap":"0.3125rem"}},"layout":{"type":"flex","flexWrap":"wrap","verticalAlignment":"center"}} --> | ||
| <div class="wp-block-group itin-drinks-wrapper"><!-- wp:group {"style":{"spacing":{"blockGap":"0.3125rem"}},"layout":{"type":"flex","flexWrap":"nowrap","verticalAlignment":"center"}} --> | ||
| <div class="wp-block-group"><!-- wp:lsx-tour-operator/icons {"iconType":"solid","iconName":"drinksBasisIcon"} /--> | ||
|
|
||
| <!-- wp:paragraph {"style":{"typography":{"fontStyle":"normal","fontWeight":"700"}},"fontSize":"medium"} --> | ||
| <p class="has-medium-font-size" style="font-style:normal;font-weight:700">' . esc_html__( 'Drinks Basis:', 'tour-operator' ) . '</p> | ||
| <!-- wp:group {"metadata":{"name":"Drinks Basis Row"},"className":"itin-drinks-wrapper","style":{"spacing":{"blockGap":"0.3125rem"}},"layout":{"type":"flex","flexWrap":"nowrap","verticalAlignment":"top"}} --> | ||
| <div class="wp-block-group itin-drinks-wrapper"><!-- wp:lsx-tour-operator/icons {"iconType":"solid","iconName":"drinksBasisIcon"} /--> | ||
| <!-- wp:paragraph {"metadata":{"name":"Drinks Basis Value"},"className":"itinerary-drinks","fontSize":"medium","prefix":"Drinks Basis:","prefixBold":true} --> | ||
| <p class="itinerary-drinks has-medium-font-size">Card Link</p> | ||
| <!-- /wp:paragraph --></div> | ||
| <!-- /wp:group --> | ||
|
|
||
| <!-- wp:paragraph {"metadata":{"name":"' . esc_attr__( 'Drinks Basis Value', 'tour-operator' ) . '"},"className":"itinerary-drinks","fontSize":"medium"} --> | ||
| <p class="itinerary-drinks has-medium-font-size">' . esc_html__( 'Card Link', 'tour-operator' ) . '</p> | ||
| <!-- /wp:paragraph --></div> | ||
| <!-- /wp:group --> | ||
|
|
||
| <!-- wp:group {"metadata":{"name":"' . esc_attr__( 'Room Basis Row', 'tour-operator' ) . '"},"className":"itin-room-wrapper","style":{"spacing":{"blockGap":"0.3125rem"}},"layout":{"type":"flex","flexWrap":"wrap","verticalAlignment":"center"}} --> | ||
| <div class="wp-block-group itin-room-wrapper"><!-- wp:group {"style":{"spacing":{"blockGap":"0.3125rem"}},"layout":{"type":"flex","flexWrap":"nowrap","verticalAlignment":"center"}} --> | ||
| <div class="wp-block-group"><!-- wp:lsx-tour-operator/icons {"iconType":"solid","iconName":"roomBasisIcon"} /--> | ||
|
|
||
| <!-- wp:paragraph {"style":{"typography":{"fontStyle":"normal","fontWeight":"700"}},"fontSize":"medium"} --> | ||
| <p class="has-medium-font-size" style="font-style:normal;font-weight:700">' . esc_html__( 'Room Basis:', 'tour-operator' ) . '</p> | ||
| <!-- wp:group {"metadata":{"name":"Room Basis Row"},"className":"itin-room-wrapper","style":{"spacing":{"blockGap":"0.3125rem"}},"layout":{"type":"flex","flexWrap":"nowrap","verticalAlignment":"top"}} --> | ||
| <div class="wp-block-group itin-room-wrapper"><!-- wp:lsx-tour-operator/icons {"iconType":"solid","iconName":"roomBasisIcon"} /--> | ||
| <!-- wp:paragraph {"metadata":{"name":"Room Basis Value"},"className":"itinerary-room","fontSize":"medium","prefix":"Room Basis:","prefixBold":true} --> | ||
| <p class="itinerary-room has-medium-font-size">Card Link</p> | ||
| <!-- /wp:paragraph --></div> | ||
| <!-- /wp:group --> | ||
|
|
||
| <!-- wp:paragraph {"metadata":{"name":"' . esc_attr__( 'Room Basis Value', 'tour-operator' ) . '"},"className":"itinerary-room","fontSize":"medium"} --> | ||
| <p class="itinerary-room has-medium-font-size">' . esc_html__( 'Card Link', 'tour-operator' ) . '</p> | ||
| <!-- /wp:paragraph --></div> | ||
| <!-- /wp:group --></div> | ||
| <!-- /wp:group --></div> | ||
|
|
||
| </div><!-- /wp:group --></div> |
There was a problem hiding this comment.
This refactoring has introduced internationalization (i18n) regressions. Several strings that were previously translatable are now hardcoded:
- The placeholder text
Card Linkis no longer wrapped in a translation function likeesc_html__(). - The
metadata.nameattributes in the block comments (e.g.,"name":"Location Row") are also hardcoded and should be made translatable withesc_attr__().
Please wrap these strings in the appropriate WordPress translation functions to ensure the pattern is fully localizable.
| //$pattern_registry = \WP_Block_Patterns_Registry::get_instance(); | ||
| //$pattern_registry->get_registered(); |
| case 'location': | ||
| $value = lsx_to_itinerary_destinations( '', '', false ); | ||
| $pattern = '/(<p\s+[^>]*\bclass="[^"]*\bitinerary-location\b[^"]*"[^>]*>).*?(<\/p>)/is'; | ||
| $prefix = $this->maybe_get_prefix( 'itinerary-location', $build ); | ||
| break; | ||
|
|
||
| case 'accommodation': | ||
| $value = lsx_to_itinerary_accommodation( '', '', false ); | ||
| $pattern = '/(<p\s+[^>]*\bclass="[^"]*\bitinerary-accommodation\b[^"]*"[^>]*>).*?(<\/p>)/is'; | ||
| $prefix = $this->maybe_get_prefix( 'itinerary-accommodation', $build ); | ||
| break; | ||
|
|
||
| case 'type': | ||
| $value = lsx_to_itinerary_accommodation_type( '', '', false ); | ||
| $pattern = '/(<p\s+[^>]*\bclass="[^"]*\bitinerary-type\b[^"]*"[^>]*>).*?(<\/p>)/is'; | ||
| $prefix = $this->maybe_get_prefix( 'itinerary-type', $build ); | ||
| break; | ||
|
|
||
| case 'drinks': | ||
| $value = lsx_to_itinerary_drinks_basis( '', '', false ); | ||
| $pattern = '/(<p\s+[^>]*\bclass="[^"]*\bitinerary-drinks\b[^"]*"[^>]*>).*?(<\/p>)/is'; | ||
| $prefix = $this->maybe_get_prefix( 'itinerary-drinks', $build ); | ||
| break; | ||
|
|
||
| case 'room': | ||
| $value = lsx_to_itinerary_room_basis( '', '', false ); | ||
| $pattern = '/(<p\s+[^>]*\bclass="[^"]*\bitinerary-room\b[^"]*"[^>]*>).*?(<\/p>)/is'; | ||
| $prefix = $this->maybe_get_prefix( 'itinerary-room', $build ); | ||
| break; |
There was a problem hiding this comment.
The switch statement contains a lot of repetitive code for cases 'location', 'accommodation', 'type', 'drinks', and 'room'. This could be refactored to be more concise and maintainable by using a data structure like an associative array to map fields to their respective functions and then handling them generically.
For example:
$field_map = [
'location' => 'lsx_to_itinerary_destinations',
'accommodation' => 'lsx_to_itinerary_accommodation',
'type' => 'lsx_to_itinerary_accommodation_type',
'drinks' => 'lsx_to_itinerary_drinks_basis',
'room' => 'lsx_to_itinerary_room_basis',
];
if ( array_key_exists( $field, $field_map ) ) {
$value = call_user_func( $field_map[ $field ], '', '', false );
$pattern = '/(<p\s+[^>]*\bclass="[^"]*\bitinerary-' . $field . '\b[^"]*"[^>]*>).*?(<\/p>)/is';
$prefix = $this->maybe_get_prefix( 'itinerary-' . $field, $build );
break;
}| @@ -408,6 +417,9 @@ public function build_itinerary_field( $build = '', $field = '', $count = 1 ) { | |||
| if ( '' === $value || false === $value || empty( $value ) ) { | |||
There was a problem hiding this comment.
| // Get the raw unfiltered value. | ||
| $value = get_post_meta( get_the_ID(), $meta_key, true ); |
There was a problem hiding this comment.
While using get_post_meta() directly to get the raw value is a valid approach, it bypasses the lsx_to_custom_field_query() function which might contain important logic or filters. Ensure that this change is intentional and that bypassing the existing helper function doesn't lead to unintended side effects or inconsistencies in how meta values are retrieved across the plugin.
| /** | ||
| * lsx_to_related_connection_found_items filter. | ||
| * @var $key | ||
| * @var $current_item_ID | ||
| */ |
There was a problem hiding this comment.
The PHPDoc for this filter is incorrect. The filter name in the comment (lsx_to_related_connection_found_items) does not match the one being used (lsx_to_related_connection_query_key), and @var should be @param for function/filter parameters. Please correct the docblock to accurately reflect the filter being added.
/**
* Filters the meta key for the related connection query.
*
* @param string $key The meta key, e.g., '{$to}_to_{$from}'.
* @param int $current_item_ID The current post ID.
*/…nt argument for post connection
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (4)
build/blocks/destination-to-tour/index.asset.php(1 hunks)build/blocks/destination-to-tour/index.js(1 hunks)changelog.md(1 hunks)src/blocks/destination-to-tour/index.js(1 hunks)
🧰 Additional context used
📓 Path-based instructions (14)
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Use semicolons to terminate statements in JavaScript block code
Ensure all generated code follows ESLint rules and WordPress Coding Standards before deployment
Files:
build/blocks/destination-to-tour/index.jssrc/blocks/destination-to-tour/index.js
**/*.{php,js,jsx,ts,tsx,json}
📄 CodeRabbit inference engine (GEMINI.md)
Follow WordPress Coding Standards including proper namespacing, security practices (sanitization/escaping), and code organization
Files:
build/blocks/destination-to-tour/index.jssrc/blocks/destination-to-tour/index.jsbuild/blocks/destination-to-tour/index.asset.php
**/*.{js,jsx,ts,tsx,php}
📄 CodeRabbit inference engine (GEMINI.md)
Implement accessibility features following WCAG 2.2 AA standards in all block components and patterns
Files:
build/blocks/destination-to-tour/index.jssrc/blocks/destination-to-tour/index.jsbuild/blocks/destination-to-tour/index.asset.php
**/*.{php,js,jsx,ts,tsx}
📄 CodeRabbit inference engine (GEMINI.md)
Validate generated code against WordPress standards, test thoroughly, check security implications, and review for proper sanitization/escaping
Files:
build/blocks/destination-to-tour/index.jssrc/blocks/destination-to-tour/index.jsbuild/blocks/destination-to-tour/index.asset.php
**/*.{js,jsx,ts,tsx,php,scss,css}
📄 CodeRabbit inference engine (GEMINI.md)
Use camelCase for variable and function names, kebab-case for CSS classes, and snake_case for PHP variable names per WordPress Coding Standards
Files:
build/blocks/destination-to-tour/index.jssrc/blocks/destination-to-tour/index.jsbuild/blocks/destination-to-tour/index.asset.php
**/*.{js,jsx,ts,tsx,scss,css}
📄 CodeRabbit inference engine (GEMINI.md)
For performance optimization, implement code splitting, lazy loading, and minimize CSS/JavaScript bundle sizes in block components
Files:
build/blocks/destination-to-tour/index.jssrc/blocks/destination-to-tour/index.js
**/*.{js,ts,tsx,jsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.{js,ts,tsx,jsx}: Use async/await syntax; avoid .then() chains
Use named exports; avoid default exports unless wrapping a module
Files:
build/blocks/destination-to-tour/index.jssrc/blocks/destination-to-tour/index.js
src/blocks/**/*.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use Block API v3 standards when developing blocks
Files:
src/blocks/destination-to-tour/index.js
{src/blocks/**/*.{js,jsx,ts,tsx},src/**/*.php,inc/**/*.php}
📄 CodeRabbit inference engine (AGENTS.md)
Apply WCAG 2.2 AA accessibility standards to all blocks and UI components
Files:
src/blocks/destination-to-tour/index.js
src/**/*.{js,ts,tsx,jsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/**/*.{js,ts,tsx,jsx}: Document public functions with JSDoc
Do not include any WordPress-related imports, functions, or file structures
Do not reference or assume plugins like WooCommerce or Wetu
Files:
src/blocks/destination-to-tour/index.js
**/blocks/**/*.php
📄 CodeRabbit inference engine (CLAUDE.md)
PHP render callbacks must be properly documented with descriptions of attributes and return values
Files:
build/blocks/destination-to-tour/index.asset.php
**/*.php
📄 CodeRabbit inference engine (AGENTS.md)
Follow WordPress Coding Standards (WPCS) for all WordPress code
**/*.php: Store block patterns in the/patterns/directory at the root of the plugin (WordPress standard for plugins), not in/includes/patterns/
Use text domain 'tour-operator' for all localization strings in the plugin
Files:
build/blocks/destination-to-tour/index.asset.php
**/*.{php,html}
📄 CodeRabbit inference engine (.github/instructions/patterns-templates-refactoring.instructions.md)
**/*.{php,html}: Always useLSX_TO_URLandLSX_TO_PATHconstants for asset paths in plugin files
Include CSS variable fallbacks with absolute hex values in inline styles for plugin compatibility with any theme
Use CSS variable formatvar(--wp--preset--[type]--[name], fallback_value)in inline styles, notvar:preset|[type]|[name]format
Usevar:preset|[type]|[name]format only within JSON block attributes, not in inline styles
Use the correct spacing preset names: 'tiny' (10px), 'small' (16px), 'medium' (32px), 'large' (48px), and 'x-small' (8px)
Files:
build/blocks/destination-to-tour/index.asset.php
**/*.{php,twig}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Do not generate .php, .twig, or legacy CMS files
Files:
build/blocks/destination-to-tour/index.asset.php
🧬 Code graph analysis (1)
build/blocks/destination-to-tour/index.js (2)
build/blocks/units/index.js (4)
t(1-1)e(1-1)n(1-1)s(1-1)build/blocks/destination-to-accommodation/index.js (4)
t(1-1)o(1-1)a(1-1)s(1-1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Summary
🔇 Additional comments (1)
src/blocks/destination-to-tour/index.js (1)
79-79: Thelsx/post-connectionbinding source properly supports theparentsparameter.The parameter is correctly implemented in the
post_connections_callbackmethod at lines 179–181 ofincludes/classes/blocks/class-bindings.php, where it filters the post list to include only top-level items when set totrue. Existing block instances without this parameter maintain current functionality since the default value isfalse, ensuring backward compatibility.
| - **Sticky Menu Block** - Added sticky navigation menu block with desktop and mobile navigation support for single post templates, includes anchor support and section group functionality - [#684](https://github.com/lightspeedwp/tour-operator/pull/684), Issue [#496](https://github.com/lightspeedwp/tour-operator/issues/496) | ||
| - **TO Videos Block** - Added YouTube video gallery block for displaying videos on tours, accommodation, and destination templates in a professional gallery layout - [#598](https://github.com/lightspeedwp/tour-operator/pull/598), Issue [#397](https://github.com/lightspeedwp/tour-operator/issues/397) | ||
| - **Check-in/Checkout Time Icon Blocks** - Added icon-based blocks (replacing images) for check-in and checkout times with filters to display only on relevant post types (accommodation) and related templates - [#645](https://github.com/lightspeedwp/tour-operator/pull/645) | ||
| - **Unit Blocks** - Added comprehensive unit blocks functionality with refined assets and WordPress coding standards alignment - [#815](https://github.com/lightspeedwp/tour-operator/pull/815) |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Expand the changelog entry with more detail.
The Unit Blocks changelog entry is quite brief compared to other entries in this section. Consider adding more detail about:
- What unit blocks functionality was added
- What specific assets were refined
- What WordPress coding standards alignment changes were made
This will help users better understand the scope of changes in this release.
🤖 Prompt for AI Agents
In changelog.md around line 36, expand the single-line "Unit Blocks" entry into
a more descriptive paragraph that lists what unit block functionality was added
(e.g., new block types, settings, and editor interactions), specifies which
assets were refined (e.g., updated stylesheets, SVG icons, JS bundle size
optimizations and image assets), and enumerates the WordPress coding standards
alignment changes (e.g., PHP linting fixes, sanitized inputs, docblock updates,
and PSR-style formatting). Replace the terse line with a concise 2–4 sentence
entry covering these points and include the existing PR reference and issue
number for traceability.
This PR merges the
feature/unit-blocksbranch into2.1-trunk.Summary
Notes
changelog.mdaccordinglySummary by CodeRabbit
New Features
Improvements
Chores
✏️ Tip: You can customize this high-level summary in your review settings.