Skip to content

Conversation

@koriym
Copy link
Member

@koriym koriym commented Jul 7, 2025

Summary

  • Add ToArrayInterface and ToArray implementation for converting nested Input objects to flat associative arrays
  • Enable SQL parameter binding from hierarchical Input structures
  • Handle property name conflicts with later-wins strategy
  • Preserve arrays for SQL IN clause compatibility (Aura.Sql)

Key Features

  • Recursive flattening: Nested Input objects are recursively expanded
  • Property conflict resolution: Later properties overwrite earlier ones
  • Array preservation: Arrays remain intact for SQL IN clauses
  • Access control: Only public properties are processed
  • Type safety: Maintains type information through transformation

Usage Example

$orderInput = new OrderInput(
    customerId: '123',
    customer: new CustomerInput(name: 'John', email: 'john@example.com'),
    items: [['id' => 1, 'qty' => 2]]
);

$toArray = new ToArray();
$params = $toArray($orderInput);
// Result: ['customerId' => '123', 'name' => 'John', 'email' => 'john@example.com', 'items' => [...]]

// Use with SQL
$sql = "SELECT * FROM orders WHERE customer_id = :customerId AND items IN (:items)";
$stmt->execute($params);

Test Coverage

  • Simple object flattening
  • Nested object hierarchy
  • Array property preservation
  • Property name conflict handling
  • Private property exclusion
  • Null value handling

🤖 Generated with Claude Code

Summary by Sourcery

Implement ToArray functionality for flattening hierarchical Input objects into flat arrays with correct conflict resolution, array preservation, and public property filtering to support SQL parameter binding.

New Features:

  • Introduce ToArrayInterface and ToArray to convert nested Input-annotated objects to flat associative arrays

Enhancements:

  • Recursively flatten nested objects, preserve arrays for SQL IN clauses, resolve conflicting property names by later-wins, and ignore private properties while handling null values

Tests:

  • Add comprehensive ToArrayTest cases covering simple objects, nested hierarchies, array properties, name conflicts, private property exclusion, and null value handling

Summary by CodeRabbit

  • New Features

    • Added the ability to convert objects with public properties into flat associative arrays, including support for nested objects and arrays.
  • Tests

    • Introduced comprehensive tests to verify object-to-array conversion, including handling of nested objects, arrays, property conflicts, private properties, and null values.
  • Documentation

    • Updated README with detailed usage examples and explanations for the new object-to-array conversion feature, including handling of property conflicts and nested data structures.

- Add ToArrayInterface for converting Input objects to flat arrays
- Add ToArray implementation with recursive object flattening
- Handle property name conflicts (later values overwrite earlier ones)
- Preserve arrays for SQL IN clause compatibility
- Ignore private/protected properties (public only)
- Add comprehensive test suite covering all edge cases

This enables SQL parameter binding from nested Input objects:
$params = $toArray($orderInput); // Flat array for SQL queries

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Jul 7, 2025

Reviewer's Guide

This PR introduces a new ToArrayInterface and its ToArray implementation to convert hierarchical Input objects into flat associative arrays via reflection, recursively unpacking public properties, resolving name conflicts with a later-wins policy, preserving arrays for SQL IN compatibility, excluding private properties, and handling nulls, backed by a comprehensive PHPUnit test suite.

Class diagram for ToArray and ToArrayInterface

classDiagram
    class ToArrayInterface {
        <<interface>>
        +__invoke(object $input): array
    }
    class ToArray {
        +__invoke(object $input): array
        -extractProperties(object $object): array
    }
    ToArray ..|> ToArrayInterface
Loading

Flow diagram for recursive flattening in ToArray

flowchart TD
    A[Input object] --> B{Public property?}
    B -- No --> C[Skip property]
    B -- Yes --> D{Is object?}
    D -- Yes --> E[Recursively extract properties]
    D -- No --> F{Is array?}
    F -- Yes --> G[Preserve array]
    F -- No --> H[Add scalar value]
    E --> I[Add extracted properties to result]
    G --> I
    H --> I
    I --> J[Return flat associative array]
Loading

File-Level Changes

Change Details Files
Define interface for flattening Input objects
  • Add ToArrayInterface with __invoke(object): array signature
  • Document its purpose for flat associative array conversion
src/ToArrayInterface.php
Implement ToArray flattening logic
  • Use ReflectionClass to iterate public properties
  • Recursively extract nested object properties
  • Apply later-wins strategy for conflicting names
  • Preserve arrays and null values
  • Ignore private properties
src/ToArray.php
Cover flattening behavior with tests
  • Test simple object flattening
  • Test nested object hierarchy
  • Test array property preservation
  • Test property name conflict resolution
  • Test private property exclusion
  • Test null value handling
tests/ToArrayTest.php

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai
Copy link

coderabbitai bot commented Jul 7, 2025

Walkthrough

A new ToArray utility has been introduced, including its interface and a comprehensive test suite. This utility recursively converts objects with public properties into flat associative arrays, handling nested objects, arrays, and various edge cases. The interface defines the contract, the class implements the logic, and tests validate the behavior.

Changes

File(s) Change Summary
src/ToArray.php, src/ToArrayInterface.php Added ToArray class implementing ToArrayInterface with __invoke(object $input): array method.
tests/ToArrayTest.php Added ToArrayTest PHPUnit class with multiple tests covering object-to-array conversion scenarios and edge cases.
README.md Revised extensively to add documentation on ToArray usage, improve examples, and restructure content.
CHANGELOG.md Added version 0.2.0 entry documenting the addition of ToArrayInterface and ToArray implementation.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant ToArray
    participant InputObject

    Client->>ToArray: __invoke(InputObject)
    ToArray->>InputObject: Inspect public properties
    alt Property is object
        ToArray->>ToArray: Recursively extract properties
    else Property is array or scalar
        ToArray->>ToArray: Include as-is
    end
    ToArray-->>Client: Return flat associative array
Loading

Poem

In the meadow of code, where objects do play,
A rabbit hops in, making arrays from clay.
With reflection it peers, through each public door,
Flattening secrets, but never a bore.
Now tests bloom like flowers, all passing—hooray!
Arrays from objects, the rabbit’s new way.
🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey @koriym - I've reviewed your changes - here's some feedback:

  • extractProperties currently serializes all public properties; consider filtering by the #[Input] attribute so only explicitly annotated fields are flattened.
  • Right now objects nested inside arrays are kept intact; you may want to recursively flatten Input objects within arrays as well for consistency.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- extractProperties currently serializes all public properties; consider filtering by the #[Input] attribute so only explicitly annotated fields are flattened.
- Right now objects nested inside arrays are kept intact; you may want to recursively flatten Input objects within arrays as well for consistency.

## Individual Comments

### Comment 1
<location> `src/ToArray.php:47` </location>
<code_context>
+                continue;
+            }
+
+            // Keep arrays and scalar values as-is
+            /** @psalm-suppress MixedAssignment */
+            $result[$name] = $value;
</code_context>

<issue_to_address>
Arrays containing objects are not recursively processed.

Arrays of objects are not deeply converted; further logic is required for recursive conversion if needed.
</issue_to_address>

<suggested_fix>
<<<<<<< SEARCH
            // Keep arrays and scalar values as-is
            /** @psalm-suppress MixedAssignment */
            $result[$name] = $value;
=======
            // Recursively process arrays of objects
            if (is_array($value)) {
                $processedArray = [];
                foreach ($value as $k => $v) {
                    if (is_object($v)) {
                        $processedArray[$k] = $this->extractProperties($v);
                    } else {
                        $processedArray[$k] = $v;
                    }
                }
                /** @psalm-suppress MixedAssignment */
                $result[$name] = $processedArray;
            } else {
                // Keep scalar values as-is
                /** @psalm-suppress MixedAssignment */
                $result[$name] = $value;
            }
>>>>>>> REPLACE

</suggested_fix>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

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

🧹 Nitpick comments (1)
tests/ToArrayTest.php (1)

36-77: Remove unused variable.

The $author variable on line 38 is declared but never used, making it dead code.

-        $author = new class {
-            public function __construct(
-                #[Input]
-                public readonly string $name = 'John',
-                #[Input]
-                public readonly string $email = 'john@example.com',
-            ) {
-            }
-        };
-
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3f5f77b and 398ef06.

📒 Files selected for processing (3)
  • src/ToArray.php (1 hunks)
  • src/ToArrayInterface.php (1 hunks)
  • tests/ToArrayTest.php (1 hunks)
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: CR
PR: ray-di/Ray.InputQuery#0
File: docs/CLAUDE.md:0-0
Timestamp: 2025-07-03T12:18:36.698Z
Learning: Applies to docs/src/InputQuery.php : For parameters with #[Input] and object type, extract prefixed keys from flat query and recursively create nested objects.
src/ToArrayInterface.php (3)
Learnt from: CR
PR: ray-di/Ray.InputQuery#0
File: docs/CLAUDE.md:0-0
Timestamp: 2025-07-03T12:18:36.698Z
Learning: Applies to docs/src/InputQuery.php : For parameters with #[Input] and object type, extract prefixed keys from flat query and recursively create nested objects.
Learnt from: CR
PR: ray-di/Ray.InputQuery#0
File: docs/CLAUDE.md:0-0
Timestamp: 2025-07-03T12:18:36.698Z
Learning: Applies to docs/src/InputQueryInterface.php : InputQueryInterface must define getArguments(ReflectionMethod $method, array $query): array and create(string $class, array $query): object.
Learnt from: CR
PR: ray-di/Ray.InputQuery#0
File: docs/CLAUDE.md:0-0
Timestamp: 2025-07-03T12:18:36.698Z
Learning: Applies to docs/**/*.php : Every parameter sourced from query data must have the #[Input] attribute.
src/ToArray.php (1)
Learnt from: CR
PR: ray-di/Ray.InputQuery#0
File: docs/CLAUDE.md:0-0
Timestamp: 2025-07-03T12:18:36.698Z
Learning: Applies to docs/src/InputQuery.php : For parameters with #[Input] and object type, extract prefixed keys from flat query and recursively create nested objects.
tests/ToArrayTest.php (4)
Learnt from: CR
PR: ray-di/Ray.InputQuery#0
File: docs/CLAUDE.md:0-0
Timestamp: 2025-07-03T12:18:36.698Z
Learning: Applies to docs/**/*.php : Every parameter sourced from query data must have the #[Input] attribute.
Learnt from: CR
PR: ray-di/Ray.InputQuery#0
File: docs/CLAUDE.md:0-0
Timestamp: 2025-07-03T12:18:36.698Z
Learning: Applies to docs/src/InputQuery.php : For parameters with #[Input] and object type, extract prefixed keys from flat query and recursively create nested objects.
Learnt from: CR
PR: ray-di/Ray.InputQuery#0
File: docs/CLAUDE.md:0-0
Timestamp: 2025-07-03T12:18:36.698Z
Learning: Applies to docs/**/*.php : The #[Input] attribute must be applied to parameters, not classes.
Learnt from: CR
PR: ray-di/Ray.InputQuery#0
File: docs/CLAUDE.md:0-0
Timestamp: 2025-07-03T12:18:36.698Z
Learning: Applies to docs/src/Attribute/Input.php : Attribute class Input must be defined as #[Attribute(Attribute::TARGET_PARAMETER)] in src/Attribute/Input.php.
🧬 Code Graph Analysis (1)
src/ToArray.php (2)
src/InputQuery.php (1)
  • InputQuery (70-506)
src/ToArrayInterface.php (1)
  • __invoke (16-16)
🪛 PHPMD (2.15.0)
tests/ToArrayTest.php

24-24: Avoid unused parameters such as '$name'. (Unused Code Rules)

(UnusedFormalParameter)


26-26: Avoid unused parameters such as '$age'. (Unused Code Rules)

(UnusedFormalParameter)


38-38: Avoid unused local variables such as '$author'. (Unused Code Rules)

(UnusedLocalVariable)


61-61: Avoid unused parameters such as '$name'. (Unused Code Rules)

(UnusedFormalParameter)


63-63: Avoid unused parameters such as '$email'. (Unused Code Rules)

(UnusedFormalParameter)


85-85: Avoid unused parameters such as '$status'. (Unused Code Rules)

(UnusedFormalParameter)


87-87: Avoid unused parameters such as '$userIds'. (Unused Code Rules)

(UnusedFormalParameter)


115-115: Avoid unused parameters such as '$id'. (Unused Code Rules)

(UnusedFormalParameter)


117-117: Avoid unused parameters such as '$name'. (Unused Code Rules)

(UnusedFormalParameter)


138-138: Avoid unused parameters such as '$public'. (Unused Code Rules)

(UnusedFormalParameter)


140-140: Avoid unused parameters such as '$private'. (Unused Code Rules)

(UnusedFormalParameter)


156-156: Avoid unused parameters such as '$name'. (Unused Code Rules)

(UnusedFormalParameter)


158-158: Avoid unused parameters such as '$email'. (Unused Code Rules)

(UnusedFormalParameter)


160-160: Avoid unused parameters such as '$address'. (Unused Code Rules)

(UnusedFormalParameter)

🔇 Additional comments (10)
src/ToArrayInterface.php (1)

7-17: LGTM! Clean interface design with clear documentation.

The interface is well-structured with appropriate type declarations and comprehensive documentation. The method signature clearly conveys the intent and return type.

src/ToArray.php (2)

13-22: LGTM! Correct implementation of the interface.

The class properly implements ToArrayInterface with the #[Override] attribute and delegates to the private extraction method.


24-53: LGTM! Robust recursive property extraction with intentional conflict resolution.

The implementation correctly:

  • Uses reflection to access only public properties
  • Recursively flattens nested objects
  • Preserves arrays and scalar values as-is
  • Handles property name conflicts by allowing nested properties to overwrite parent properties (as demonstrated in the test cases)

The recursive approach effectively flattens hierarchical Input structures for SQL parameter binding as intended.

tests/ToArrayTest.php (7)

10-17: LGTM! Proper test setup with dependency injection.

The test class follows good practices with proper setup and type-hinted dependencies.


19-34: LGTM! Comprehensive test for simple object conversion.

The test correctly validates basic object-to-array conversion with readonly properties and #[Input] attributes.


48-77: LGTM! Excellent test for nested object flattening.

The test correctly validates that nested objects are recursively flattened into a single-level array, which is the core functionality of this feature.


79-98: LGTM! Important test for array preservation.

This test correctly validates that arrays are preserved as-is, which is crucial for SQL IN clause compatibility as mentioned in the PR objectives.


100-131: LGTM! Critical test for property name conflict resolution.

This test correctly validates the intentional behavior where nested properties overwrite parent properties with the same name. The comment clearly explains the expected behavior.


133-149: LGTM! Important test for access control.

This test correctly validates that private properties are ignored, ensuring proper encapsulation and access control.


151-172: LGTM! Proper handling of null values.

This test correctly validates that null values are preserved in the output array, which is important for nullable database columns.

- Add intuitive Quick Example showing query string → hierarchical objects
- Replace complex overview with simple, immediate value demonstration
- Move Demo section to end (logical flow: learn → understand → try)
- Remove unnecessary PSR-7 example, focus on simple $_POST usage
- Add comprehensive ToArray documentation with Aura.Sql integration
- Update CHANGELOG for v0.2.0 release with ToArray functionality

The README now answers "what is this?" in 3 seconds with concrete examples.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
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

🧹 Nitpick comments (5)
CHANGELOG.md (2)

10-12: Grammar & clarity tweak for the bullet point
The phrase reads awkwardly and currently implies two separate entities when only one implementation exists.

- - `ToArrayInterface` and `ToArray` implementation for flattening objects to flat associative arrays
+ - `ToArrayInterface` and a `ToArray` implementation for flattening objects into flat associative arrays

45-45: Missing backlink for the new release tag
Every version section should have its reference link at the bottom to keep navigation consistent.

 [0.1.0]: https://github.com/ray-di/Ray.InputQuery/releases/tag/0.1.0
+[0.2.0]: https://github.com/ray-di/Ray.InputQuery/releases/tag/0.2.0
README.md (3)

12-15: Code snippet is missing the Input import
Without the import the snippet will not compile as-is and may confuse new users.

-// HTTP Request: ?name=John&email=john@example.com&addressStreet=123 Main St&addressCity=Tokyo
+use Ray\InputQuery\Attribute\Input;
+
+// HTTP Request: ?name=John&email=john@example.com&addressStreet=123 Main St&addressCity=Tokyo

30-33: Undefined $inputQuery in quick example
Showing instantiation (or at least a short comment) prevents readers from wondering where the variable comes from.
Even a single-line comment like // assume $inputQuery is an InputQuery instance would suffice.


549-551: Typo in section heading – double “¥” characters

-### SQL Param¥¥eter Binding
+### SQL Parameter Binding
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 398ef06 and f6bced4.

📒 Files selected for processing (2)
  • CHANGELOG.md (2 hunks)
  • README.md (2 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: CR
PR: ray-di/Ray.InputQuery#0
File: docs/CLAUDE.md:0-0
Timestamp: 2025-07-03T12:18:36.698Z
Learning: Applies to docs/src/InputQuery.php : For parameters with #[Input] and object type, extract prefixed keys from flat query and recursively create nested objects.
README.md (10)
Learnt from: CR
PR: ray-di/Ray.InputQuery#0
File: docs/CLAUDE.md:0-0
Timestamp: 2025-07-03T12:18:36.698Z
Learning: Applies to docs/**/*.php : Every parameter sourced from query data must have the #[Input] attribute.
Learnt from: CR
PR: ray-di/Ray.InputQuery#0
File: docs/CLAUDE.md:0-0
Timestamp: 2025-07-03T12:18:36.698Z
Learning: Applies to docs/src/InputQuery.php : For parameters with #[Input] and object type, extract prefixed keys from flat query and recursively create nested objects.
Learnt from: CR
PR: ray-di/Ray.InputQuery#0
File: docs/CLAUDE.md:0-0
Timestamp: 2025-07-03T12:18:36.698Z
Learning: Applies to docs/src/InputQuery.php : For parameters without #[Input], resolve them from the DI container, supporting #[Named] for scalar DI values.
Learnt from: CR
PR: ray-di/Ray.InputQuery#0
File: docs/CLAUDE.md:0-0
Timestamp: 2025-07-03T12:18:36.698Z
Learning: Applies to docs/src/InputQuery.php : Parameters without #[Input] that can't be resolved by DI: use parameter default or throw exception.
Learnt from: CR
PR: ray-di/Ray.InputQuery#0
File: docs/CLAUDE.md:0-0
Timestamp: 2025-07-03T12:18:36.698Z
Learning: Applies to docs/src/InputQuery.php : Parameters with #[Input] but missing from query: use parameter default or null if allowed.
Learnt from: CR
PR: ray-di/Ray.InputQuery#0
File: docs/CLAUDE.md:0-0
Timestamp: 2025-07-03T12:18:36.698Z
Learning: Applies to docs/src/InputQuery.php : Convert all query keys to camelCase, handling snake_case, kebab-case, and PascalCase.
Learnt from: CR
PR: ray-di/Ray.InputQuery#0
File: docs/CLAUDE.md:0-0
Timestamp: 2025-07-03T12:18:36.698Z
Learning: Applies to docs/**/*.php : The #[Input] attribute must be applied to parameters, not classes.
Learnt from: CR
PR: ray-di/Ray.InputQuery#0
File: docs/CLAUDE.md:0-0
Timestamp: 2025-07-03T12:18:36.698Z
Learning: Applies to docs/src/InputQuery.php : Implement a reasonable recursion depth limit (e.g., 10 levels) to prevent infinite recursion in nested input resolution.
Learnt from: CR
PR: ray-di/Ray.InputQuery#0
File: docs/CLAUDE.md:0-0
Timestamp: 2025-07-03T12:18:36.698Z
Learning: Applies to docs/src/Attribute/Input.php : Attribute class Input must be defined as #[Attribute(Attribute::TARGET_PARAMETER)] in src/Attribute/Input.php.
Learnt from: CR
PR: ray-di/Ray.InputQuery#0
File: docs/CLAUDE.md:0-0
Timestamp: 2025-07-03T12:18:36.698Z
Learning: Applies to docs/src/InputQueryInterface.php : InputQueryInterface must define getArguments(ReflectionMethod $method, array $query): array and create(string $class, array $query): object.
CHANGELOG.md (1)
Learnt from: CR
PR: ray-di/Ray.InputQuery#0
File: docs/CLAUDE.md:0-0
Timestamp: 2025-07-03T12:18:36.698Z
Learning: Applies to docs/**/*.php : Every parameter sourced from query data must have the #[Input] attribute.
🪛 LanguageTool
CHANGELOG.md

[uncategorized] ~11-~11: “and” (in addition to, following this) seems less likely than “a”.
Context: ...5-07-07 ### Added - ToArrayInterface and ToArray implementation for flattening...

(AI_HYDRA_LEO_CP_AND_AN)

Remove unused  variable in testNestedObject method.
The test creates the author object directly in the constructor instead.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
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

🧹 Nitpick comments (1)
tests/ToArrayTest.php (1)

1-163: Consider adding tests for additional edge cases.

While the current test coverage is comprehensive for the main use cases, consider adding tests for:

  • Empty objects with no #[Input] properties
  • Deeply nested objects (3+ levels)
  • Objects with mixed annotated/non-annotated properties
  • Performance characteristics with large nested structures

Would you like me to help generate additional edge case tests to further strengthen the test suite?

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f6bced4 and 9a4ccd3.

📒 Files selected for processing (1)
  • tests/ToArrayTest.php (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: CR
PR: ray-di/Ray.InputQuery#0
File: docs/CLAUDE.md:0-0
Timestamp: 2025-07-03T12:18:36.698Z
Learning: Applies to docs/src/InputQuery.php : For parameters with #[Input] and object type, extract prefixed keys from flat query and recursively create nested objects.
tests/ToArrayTest.php (4)
Learnt from: CR
PR: ray-di/Ray.InputQuery#0
File: docs/CLAUDE.md:0-0
Timestamp: 2025-07-03T12:18:36.698Z
Learning: Applies to docs/**/*.php : Every parameter sourced from query data must have the #[Input] attribute.
Learnt from: CR
PR: ray-di/Ray.InputQuery#0
File: docs/CLAUDE.md:0-0
Timestamp: 2025-07-03T12:18:36.698Z
Learning: Applies to docs/src/InputQuery.php : For parameters with #[Input] and object type, extract prefixed keys from flat query and recursively create nested objects.
Learnt from: CR
PR: ray-di/Ray.InputQuery#0
File: docs/CLAUDE.md:0-0
Timestamp: 2025-07-03T12:18:36.698Z
Learning: Applies to docs/**/*.php : The #[Input] attribute must be applied to parameters, not classes.
Learnt from: CR
PR: ray-di/Ray.InputQuery#0
File: docs/CLAUDE.md:0-0
Timestamp: 2025-07-03T12:18:36.698Z
Learning: Applies to docs/src/Attribute/Input.php : Attribute class Input must be defined as #[Attribute(Attribute::TARGET_PARAMETER)] in src/Attribute/Input.php.
🪛 PHPMD (2.15.0)
tests/ToArrayTest.php

24-24: Avoid unused parameters such as '$name'. (Unused Code Rules)

(UnusedFormalParameter)


26-26: Avoid unused parameters such as '$age'. (Unused Code Rules)

(UnusedFormalParameter)


51-51: Avoid unused parameters such as '$name'. (Unused Code Rules)

(UnusedFormalParameter)


53-53: Avoid unused parameters such as '$email'. (Unused Code Rules)

(UnusedFormalParameter)


75-75: Avoid unused parameters such as '$status'. (Unused Code Rules)

(UnusedFormalParameter)


77-77: Avoid unused parameters such as '$userIds'. (Unused Code Rules)

(UnusedFormalParameter)


105-105: Avoid unused parameters such as '$id'. (Unused Code Rules)

(UnusedFormalParameter)


107-107: Avoid unused parameters such as '$name'. (Unused Code Rules)

(UnusedFormalParameter)


128-128: Avoid unused parameters such as '$public'. (Unused Code Rules)

(UnusedFormalParameter)


130-130: Avoid unused parameters such as '$private'. (Unused Code Rules)

(UnusedFormalParameter)


146-146: Avoid unused parameters such as '$name'. (Unused Code Rules)

(UnusedFormalParameter)


148-148: Avoid unused parameters such as '$email'. (Unused Code Rules)

(UnusedFormalParameter)


150-150: Avoid unused parameters such as '$address'. (Unused Code Rules)

(UnusedFormalParameter)

🔇 Additional comments (7)
tests/ToArrayTest.php (7)

1-17: LGTM: Well-structured test setup.

The test class is properly structured with appropriate namespace, imports, and dependency injection setup. The use of the ToArrayInterface type hint ensures the tests work against the contract rather than the concrete implementation.


19-34: LGTM: Comprehensive test for simple object conversion.

The test correctly verifies that a simple object with #[Input] annotated properties is converted to a flat associative array. The use of constructor property promotion with readonly properties is a good practice.


36-67: LGTM: Excellent test for nested object flattening.

This test effectively demonstrates the core functionality of flattening nested objects into a single associative array. The nested author object properties are correctly merged into the top-level array, which aligns with the PR objectives for SQL parameter binding.


69-88: LGTM: Proper validation of array property preservation.

The test correctly verifies that array properties are preserved as-is rather than being flattened, which is essential for SQL IN clause compatibility as mentioned in the PR objectives.


90-121: LGTM: Critical test for property name conflict resolution.

This test validates the important behavior where later properties overwrite earlier ones when property names conflict. The comment on line 116 clearly documents this expected behavior, which is crucial for users to understand.


123-139: LGTM: Important test for access control validation.

This test ensures that private properties are correctly ignored even when annotated with #[Input], maintaining proper encapsulation. The use of assertArrayNotHasKey provides clear negative validation.


141-162: LGTM: Thorough test for null value handling.

The test correctly validates that null values are preserved in the output array, which is important for SQL parameter binding where null values have semantic meaning.

@koriym koriym merged commit 74d0fe6 into 1.x Jul 7, 2025
18 checks passed
@koriym koriym deleted the flattern branch July 7, 2025 09:32
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