Skip to content

Conversation

@ChiragAgg5k
Copy link
Member

@ChiragAgg5k ChiragAgg5k commented Nov 10, 2025

Summary by CodeRabbit

  • Bug Fixes

    • Eliminated duplicate enum imports in generated PHP code
    • Corrected template logic affecting parameter rendering
  • New Features

    • Improved enum name derivation for more consistent handling across generated code
    • Added Role import generation alongside Permission imports when needed

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 10, 2025

Walkthrough

This pull request modifies the PHP Twig template used to generate documentation examples. The changes improve enum handling by replacing hard-coded enum names with derived names (using enumName if available, otherwise the parameter name). A deduplication mechanism is added to track already-added enum names and prevent duplicate imports. The template logic is simplified by removing a conditional wrapper, and parameter rendering is adjusted to conditionally render enum types using the derived name with ::key notation. Additionally, a conditional import for Role is added when permissions are present alongside the existing Permission import.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Enum naming logic: Verify the fallback behavior between enumName and parameter name works correctly across different parameter configurations
  • Deduplication mechanism: Confirm the tracking of added enum names prevents all intended duplicates without false positives
  • Conditional wrapper removal: Assess the impact of removing the condition and ensure parameter-specific code blocks render as expected
  • Parameter rendering changes: Test the conditional enum type rendering with mixed scenarios (with/without enum values)
  • Role import addition: Verify the conditional Role import logic correctly triggers when permissions are present and doesn't introduce unintended dependencies

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 'fix: example generation for php for enums' directly and specifically describes the main change: fixing how enum examples are generated in PHP templates.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix-example-generation

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.

@abnegate abnegate merged commit 1a7a3b8 into master Nov 10, 2025
1 of 2 checks passed
Copy link
Contributor

@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: 1

🧹 Nitpick comments (1)
templates/php/docs/example.md.twig (1)

42-42: Consider extracting the enum name derivation logic.

The logic to derive the enum name (using enumName if present, otherwise name) is duplicated between lines 11-15 and line 42. While Twig has limited refactoring capabilities, this duplication could lead to inconsistencies if updated in one place but not the other.

If Twig macros are available in your setup, consider creating a reusable macro:

{% macro getEnumName(parameter) %}
{% if parameter.enumName is not empty %}{{ parameter.enumName }}{% else %}{{ parameter.name }}{% endif %}
{% endmacro %}

Then use it in both locations:

{% import _self as helpers %}
use {{ spec.title | caseUcfirst }}\Enums\{{ helpers.getEnumName(parameter) | caseUcfirst }};
...
{{ helpers.getEnumName(parameter) | caseUcfirst }}::{{ (parameter.enumKeys[0] ?? parameter.enumValues[0]) | caseEnumKey }}()
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7a34a2c and a3d0afb.

📒 Files selected for processing (1)
  • templates/php/docs/example.md.twig (2 hunks)
🔇 Additional comments (1)
templates/php/docs/example.md.twig (1)

24-24: <!-- [scratchpad_start]
[task verify_complete]
[observations]

  • Line 274 in src/SDK/Language.php shows the permission example generation:
    $prefix . 'Permission' . $staticOp . $action . '(' . $prefix . 'Role' . $staticOp . $role . '(' . $argsString . '))'
  • This generates: Permission::read(Role::any())
  • Role is ALWAYS used as an argument to Permission methods
  • The generated permission examples ALWAYS include both Permission AND Role
    [analysis]
  • The Role import in templates/php/docs/example.md.twig line 24 is CORRECT
  • Role is not imported unnecessarily - it's always needed when permissions are present
  • Permission examples always call Permission::action(Role::role(...))
  • Both imports are necessary and always used together
    [conclusion]
  • The original review comment's concern is unfounded
  • Role import is justified and necessary
  • No issues found
    [done]
    Review comment verification complete - Role is always needed with Permission
    </scratchpad_end] -->

Role import is necessary and correct.

The Role import is justified. When permission parameters are present, the generated code always uses Permission::action(Role::role(...)) format. The getPermissionExample() function in src/SDK/Language.php line 274 confirms that Role is always paired with Permission in the generated examples. Both imports are required when hasPermissionParam is true.

Comment on lines 8 to 21
{% set added = [] %}
{% for parameter in method.parameters.all %}
{% if method == parameter.required %}
{% if parameter.enumValues is not empty %}
{% if parameter.enumName is not empty %}
{% set name = parameter.enumName %}
{% else %}
{% set name = parameter.name %}
{% endif %}
{% if name not in added %}
use {{ spec.title | caseUcfirst }}\Enums\{{parameter.enumName | caseUcfirst}};
use {{ spec.title | caseUcfirst }}\Enums\{{ name | caseUcfirst }};
{% set added = added|merge([name]) %}
{% endif %}
{% endif %}
{% endif %}
{% endfor %}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Case-sensitivity mismatch in deduplication logic.

The deduplication check at line 16 uses the raw name, but the import statement at line 17 uses name | caseUcfirst. If two parameters have names that differ only in case (e.g., "status" and "Status"), both would pass the deduplication check but generate identical import statements.

Apply this diff to normalize the tracking:

 {% set added = [] %}
 {% for parameter in method.parameters.all %}
 {% if parameter.enumValues is not empty %}
 {% if parameter.enumName is not empty %}
 {% set name = parameter.enumName %}
 {% else %}
 {% set name = parameter.name %}
 {% endif %}
+{% set normalizedName = name | caseUcfirst %}
-{% if name not in added %}
+{% if normalizedName not in added %}
 use {{ spec.title | caseUcfirst }}\Enums\{{ name | caseUcfirst }};
-{% set added = added|merge([name]) %}
+{% set added = added|merge([normalizedName]) %}
 {% endif %}
 {% endif %}
 {% endfor %}
📝 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
{% set added = [] %}
{% for parameter in method.parameters.all %}
{% if method == parameter.required %}
{% if parameter.enumValues is not empty %}
{% if parameter.enumName is not empty %}
{% set name = parameter.enumName %}
{% else %}
{% set name = parameter.name %}
{% endif %}
{% if name not in added %}
use {{ spec.title | caseUcfirst }}\Enums\{{parameter.enumName | caseUcfirst}};
use {{ spec.title | caseUcfirst }}\Enums\{{ name | caseUcfirst }};
{% set added = added|merge([name]) %}
{% endif %}
{% endif %}
{% endif %}
{% endfor %}
{% set added = [] %}
{% for parameter in method.parameters.all %}
{% if parameter.enumValues is not empty %}
{% if parameter.enumName is not empty %}
{% set name = parameter.enumName %}
{% else %}
{% set name = parameter.name %}
{% endif %}
{% set normalizedName = name | caseUcfirst %}
{% if normalizedName not in added %}
use {{ spec.title | caseUcfirst }}\Enums\{{ name | caseUcfirst }};
{% set added = added|merge([normalizedName]) %}
{% endif %}
{% endif %}
{% endfor %}
🤖 Prompt for AI Agents
In templates/php/docs/example.md.twig around lines 8 to 21, the deduplication
uses the raw parameter name but the import uses name | caseUcfirst, causing
collisions when names differ only by case; compute a single
normalized/transformed variable (e.g., set importName = name | caseUcfirst) and
use importName for both the use statement and the deduplication check/merge
(added|merge([importName])) so the tracking matches the actual import string.

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.

3 participants