Skip to content

feat: Introduce NodeContext class for improved node movement handling and refactor beforeInsert, and moveNode method to use context. #46

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Jul 2, 2025

Conversation

terabytesoftw
Copy link
Member

@terabytesoftw terabytesoftw commented Jul 1, 2025

Q A
Is bugfix? ✔️
New feature?
Breaks BC?

Summary by CodeRabbit

  • New Features

    • Improved support for managing and moving nodes across multiple trees within nested set structures, allowing explicit handling of tree attributes during node operations.
    • Introduced a context-based approach for node movement operations, simplifying interaction and improving type safety.
  • Refactor

    • Enhanced efficiency and clarity of node movement operations, including centralized and optimized subtree updates when moving nodes between trees.
    • Streamlined internal logic for node repositioning with improved maintainability and database connection optimization.
    • Updated method signatures to enforce stricter type usage, improving robustness.
  • Chores

    • Updated coding style configuration to disable additional PSR-12 related fixers for consistent code formatting.
    • Removed a test verifying exception on appending to a parent with null right value.

Copy link

coderabbitai bot commented Jul 1, 2025

"""

Walkthrough

The changes refactor node movement operations in the nested set behavior by introducing a typed NodeContext object to encapsulate movement parameters, improving clarity and multi-tree support. Method signatures are updated, subtree update logic is centralized, and database connection handling is optimized. Test stubs are updated accordingly.

Changes

File(s) Change Summary
src/NestedSetsBehavior.php Refactored node movement methods to use NodeContext; added centralized subtree movement logic; optimized DB connection retrieval; added helper methods for tree value and operation state; updated insertion and update methods.
src/NodeContext.php Added new immutable NodeContext class with factory methods to represent node movement parameters and provide typed accessors.
tests/support/stub/ExtendableNestedSetsBehavior.php Updated test stubs to create and pass NodeContext instances; changed method calls to match updated signatures; passed explicit tree value to moveNodeAsRoot.
tests/NestedSetsBehaviorTest.php Changed method signature to remove nullable parameter in test stub; removed a test verifying exception on null right value.
.styleci.yml Disabled additional PSR-12 fixers: psr12_braces and psr12_class_definition.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant NestedSetsBehavior
    participant Database

    User->>NestedSetsBehavior: afterUpdate()
    NestedSetsBehavior->>NestedSetsBehavior: createMoveContext(targetNode, operation)
    NestedSetsBehavior->>NestedSetsBehavior: moveNode(NodeContext)
    alt Move as root
        NestedSetsBehavior->>NestedSetsBehavior: moveNodeAsRoot(treeValue)
        NestedSetsBehavior->>NestedSetsBehavior: moveSubtreeToTargetTree(...)
        NestedSetsBehavior->>Database: Bulk update subtree attributes
    else Move within tree
        NestedSetsBehavior->>NestedSetsBehavior: moveSubtreeToTargetTree(...)
        NestedSetsBehavior->>Database: Bulk update subtree attributes
    end
Loading

Possibly related PRs

Suggested labels

bug

Poem

In the forest of trees, where the roots intertwine,
A rabbit refactored the code—oh, so fine!
Now each tree stands tall, its value in hand,
Moving nodes with precision, just as planned.
With a hop and a leap, the logic is clear—
Multi-tree support brings us all cheer!
🐇🌳
"""


📜 Recent review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 8e5e264 and ecb689d.

📒 Files selected for processing (2)
  • src/NestedSetsBehavior.php (11 hunks)
  • src/NodeContext.php (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: terabytesoftw
PR: yii2-extensions/nested-sets-behavior#13
File: src/NestedSetsBehavior.php:145-145
Timestamp: 2025-06-29T11:22:41.839Z
Learning: The user terabytesoftw prefers to keep PRs focused and small, implementing enhancements in separate dedicated PRs rather than bundling multiple changes together.
⏰ Context from checks skipped due to timeout of 90000ms (13)
  • GitHub Check: phpunit / PHP 8.2-windows-latest
  • GitHub Check: phpunit / PHP 8.4-windows-latest
  • GitHub Check: phpunit / PHP 8.1-windows-latest
  • GitHub Check: phpunit / PHP 8.2-ubuntu-latest
  • GitHub Check: phpunit / PHP 8.1-ubuntu-latest
  • GitHub Check: phpunit-compatibility / PHP 8.4-ubuntu-latest
  • GitHub Check: phpunit / PHP 8.3-windows-latest
  • GitHub Check: phpunit-compatibility / PHP 8.2-windows-latest
  • GitHub Check: phpunit-compatibility / PHP 8.3-windows-latest
  • GitHub Check: phpunit-compatibility / PHP 8.1-windows-latest
  • GitHub Check: mutation / PHP 8.4-ubuntu-latest
  • GitHub Check: mutation / PHP 8.4-ubuntu-latest
  • GitHub Check: phpunit / PHP 8.1-windows-latest
🔇 Additional comments (13)
src/NodeContext.php (1)

1-142: Excellent implementation of the NodeContext value object.

The immutable design with factory methods provides excellent type safety and clarity for node movement operations. The encapsulation of target position calculation logic in the factory methods eliminates the need for parameter passing and reduces the chance of errors.

Key strengths:

  • Clear separation of concerns with operation-specific factory methods
  • Type-safe design with proper PHPStan annotations
  • Immutable value object pattern ensuring consistency
  • Well-documented API with clear usage examples
src/NestedSetsBehavior.php (12)

8-12: Clean import additions for enhanced functionality.

The new imports support the refactored implementation:

  • RuntimeException for better error handling in unsupported operations
  • Connection for database connection caching
  • sprintf function for consistent string formatting

125-131: Good addition of database connection caching.

The private $db property with proper documentation will improve performance by avoiding repeated database connection retrievals in operations that require multiple database calls.


261-275: Improved clarity with explicit conditional logic.

The refactoring from a match expression to explicit conditionals improves readability and makes the NodeContext integration clearer. The early return pattern for the root operation is clean and efficient.


380-402: Excellent integration of NodeContext in beforeInsert.

The match expression cleanly delegates to the appropriate NodeContext factory methods, improving type safety and eliminating manual parameter calculation. The null checks ensure proper validation before context creation.


1069-1074: Appropriate signature change for type safety.

Removing the nullable type from the $value parameter aligns with the NodeContext approach where position values are always calculated and guaranteed to be integers.


1164-1274: Well-structured moveNode refactoring with NodeContext.

The method now properly extracts values from the NodeContext and handles both same-tree and cross-tree movements. The logic correctly distinguishes between scenarios and uses appropriate update strategies.

The variable modifications in lines 1188-1190 are intentional and correct - they adjust the owner's position after the subtree shift to ensure proper boundary calculations for subsequent operations.


1294-1312: Clean refactoring of moveNodeAsRoot with better parameter handling.

The method now accepts an explicit tree value parameter and delegates subtree updates to the new moveSubtreeToTargetTree method, improving code reuse and maintainability.


1344-1361: Good delegation pattern for NodeContext integration.

The beforeInsertNodeWithContext method provides a clean bridge between the new NodeContext approach and the existing beforeInsertNode logic, maintaining backward compatibility while improving the API.


1362-1381: Robust factory method with proper error handling.

The createMoveContext method provides a centralized way to create NodeContext instances with clear exception handling for unsupported operations. The match expression covers all valid operations and provides a meaningful error message for invalid ones.


1383-1397: Efficient database connection caching implementation.

The getDb method uses null coalescing assignment for lazy initialization, ensuring the connection is cached for subsequent calls while maintaining clean code.


1423-1442: Useful utility method for tree value extraction.

The getTreeValue method centralizes tree attribute value retrieval with proper null checking, improving code consistency across the behavior.


1444-1501: Comprehensive subtree movement implementation.

The moveSubtreeToTargetTree method efficiently handles bulk updates for cross-tree movements with proper attribute updates for left, right, depth, and tree values. The single bulk operation approach is optimal for performance.

✨ 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

codecov bot commented Jul 1, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 100.00%. Comparing base (54e4fdb) to head (ecb689d).
Report is 1 commits behind head on main.

Additional details and impacted files
@@             Coverage Diff             @@
##                main       #46   +/-   ##
===========================================
  Coverage     100.00%   100.00%           
- Complexity        91       102   +11     
===========================================
  Files              2         3    +1     
  Lines            474       504   +30     
===========================================
+ Hits             474       504   +30     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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)
src/NestedSetsBehavior.php (1)

1423-1461: Verify parameter naming for clarity.

The new moveSubtreeToTargetTree() method efficiently centralizes the subtree movement logic. However, the parameter naming might be confusing:

  • $nodeRootValue: Appears to be the new tree identifier (assigned to tree attribute)
  • $treeValue: Appears to be the current tree identifier (used in WHERE condition)

Consider renaming these parameters for better clarity, e.g., $newTreeValue and $currentTreeValue.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 54e4fdb and 94cac41.

📒 Files selected for processing (2)
  • src/NestedSetsBehavior.php (9 hunks)
  • tests/support/stub/ExtendableNestedSetsBehavior.php (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: terabytesoftw
PR: yii2-extensions/nested-sets-behavior#13
File: src/NestedSetsBehavior.php:145-145
Timestamp: 2025-06-29T11:22:41.839Z
Learning: The user terabytesoftw prefers to keep PRs focused and small, implementing enhancements in separate dedicated PRs rather than bundling multiple changes together.
🧬 Code Graph Analysis (2)
tests/support/stub/ExtendableNestedSetsBehavior.php (1)
src/NestedSetsBehavior.php (2)
  • moveNode (1190-1292)
  • moveNodeAsRoot (1314-1330)
src/NestedSetsBehavior.php (2)
src/NestedSetsQueryBehavior.php (1)
  • getOwner (136-143)
tests/TestCase.php (1)
  • getDb (40-43)
⏰ Context from checks skipped due to timeout of 90000ms (13)
  • GitHub Check: phpunit / PHP 8.4-windows-latest
  • GitHub Check: phpunit / PHP 8.2-windows-latest
  • GitHub Check: phpunit / PHP 8.1-windows-latest
  • GitHub Check: phpunit / PHP 8.3-windows-latest
  • GitHub Check: phpunit-compatibility / PHP 8.2-windows-latest
  • GitHub Check: phpunit-compatibility / PHP 8.1-windows-latest
  • GitHub Check: phpunit-compatibility / PHP 8.3-windows-latest
  • GitHub Check: mutation / PHP 8.4-ubuntu-latest
  • GitHub Check: phpunit-compatibility / PHP 8.4-ubuntu-latest
  • GitHub Check: phpunit-compatibility / PHP 8.3-ubuntu-latest
  • GitHub Check: phpunit-compatibility / PHP 8.2-ubuntu-latest
  • GitHub Check: phpunit / PHP 8.2-ubuntu-latest
  • GitHub Check: mutation / PHP 8.4-ubuntu-latest
🔇 Additional comments (6)
src/NestedSetsBehavior.php (5)

9-11: LGTM! Good infrastructure improvements.

The addition of the Connection import and the private property for caching the database connection is a good optimization. The sprintf import properly supports the existing string formatting in database expressions.

Also applies to: 124-125


254-267: LGTM! Consistent implementation of multi-tree support.

The tree attribute value is correctly retrieved and passed to all movement methods. The conditional check ensures backward compatibility when treeAttribute is false.


1186-1292: LGTM! Well-structured refactoring for multi-tree support.

The method signature change and implementation improvements enhance clarity and maintainability:

  • The explicit $treeValue parameter makes the multi-tree handling more transparent
  • Centralizing the subtree movement logic in moveSubtreeToTargetTree() reduces code duplication
  • The conditional logic correctly handles both same-tree and cross-tree movements

1312-1330: LGTM! Consistent refactoring pattern.

The changes to moveNodeAsRoot() follow the same pattern as moveNode(), maintaining consistency across the codebase. The delegation to moveSubtreeToTargetTree() simplifies the implementation.


1364-1379: LGTM! Smart performance optimization.

The database connection caching using the null coalescing assignment operator (??=) is an elegant solution that prevents redundant lookups. This will improve performance when multiple database operations are performed in succession.

tests/support/stub/ExtendableNestedSetsBehavior.php (1)

57-57: LGTM! Test stub correctly updated.

The method calls are properly updated to match the new signatures in the parent class, passing null as the tree value parameter. This maintains the test compatibility while allowing the stub to exercise the updated methods.

Also applies to: 64-64

@terabytesoftw terabytesoftw requested a review from Copilot July 1, 2025 15:52
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Enhances the NestedSetsBehavior to fully support multi-tree operations by introducing a treeValue parameter in movement methods, refactors subtree moves into a single bulk operation, and adds connection caching for performance.

  • Added a treeValue argument to moveNode and moveNodeAsRoot to handle explicit tree assignment.
  • Extracted subtree update logic into moveSubtreeToTargetTree for cleaner bulk updates.
  • Introduced a cached getDb() method and updated test stubs to match new signatures.

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
tests/support/stub/ExtendableNestedSetsBehavior.php Updated exposedMoveNode and exposedMoveNodeAsRoot to pass a null treeValue.
src/NestedSetsBehavior.php Refactored node movement methods to accept and propagate treeValue, added getDb() caching, and extracted subtree logic into a new helper.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (1)
src/NestedSetsBehavior.php (1)

1190-1190: Consider using a more descriptive variable name.

The variable depthOffset would be clearer than reusing the parameter name pattern.

-$depthOffset = $targetNodeDepthValue - $ownerDepthValue + $context->depthLevelDelta;
+$depthOffset = $targetNodeDepthValue - $ownerDepthValue + $context->depthLevelDelta;
🧹 Nitpick comments (2)
src/NodeContext.php (2)

85-96: Maintain consistency in PHPDoc annotations.

Use @phpstan-var instead of @var to maintain consistency with other factory methods in this class.

 public static function forInsertBefore(ActiveRecord $targetNode, string $leftAttribute): self
 {
-    /** @var int $leftValue */
+    /** @phpstan-var int $leftValue */
     $leftValue = $targetNode->getAttribute($leftAttribute);

106-117: Maintain consistency in PHPDoc annotations.

Use @phpstan-var instead of @var to maintain consistency with other factory methods in this class.

 public static function forPrependTo(ActiveRecord $targetNode, string $leftAttribute): self
 {
-    /** @var int $leftValue */
+    /** @phpstan-var int $leftValue */
     $leftValue = $targetNode->getAttribute($leftAttribute);
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 0a4141f and 5173b83.

📒 Files selected for processing (3)
  • src/NestedSetsBehavior.php (8 hunks)
  • src/NodeContext.php (1 hunks)
  • tests/support/stub/ExtendableNestedSetsBehavior.php (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/support/stub/ExtendableNestedSetsBehavior.php
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: terabytesoftw
PR: yii2-extensions/nested-sets-behavior#13
File: src/NestedSetsBehavior.php:145-145
Timestamp: 2025-06-29T11:22:41.839Z
Learning: The user terabytesoftw prefers to keep PRs focused and small, implementing enhancements in separate dedicated PRs rather than bundling multiple changes together.
🧬 Code Graph Analysis (1)
src/NodeContext.php (1)
src/NestedSetsBehavior.php (1)
  • NestedSetsBehavior (47-1504)
🪛 GitHub Check: mutation / PHP 8.4-ubuntu-latest
src/NodeContext.php

[failure] 129-129:
Variable $depth in PHPDoc tag @var does not exist.


[failure] 129-129:
Method yii2\extensions\nestedsets\NodeContext::getTargetDepth() should return int but returns mixed.

🪛 GitHub Check: phpstan / PHP 8.4-ubuntu-latest
src/NodeContext.php

[failure] 129-129:
Variable $depth in PHPDoc tag @var does not exist.


[failure] 129-129:
Method yii2\extensions\nestedsets\NodeContext::getTargetDepth() should return int but returns mixed.

🪛 GitHub Actions: ecs
src/NodeContext.php

[error] 29-29: PhpCsFixer: SingleLineEmptyBodyFixer - Empty body should be written as {} instead of separate braces.

🔇 Additional comments (4)
src/NestedSetsBehavior.php (4)

259-278: Well-structured refactoring using NodeContext.

The refactored afterUpdate() method effectively uses the new NodeContext pattern, improving code clarity and maintainability. The early returns and centralized state reset enhance readability.


1363-1372: Excellent use of match expression and typed context creation.

The createMoveContext() method provides a clean, type-safe way to create operation-specific contexts with proper error handling for unsupported operations.


1385-1388: Smart database connection caching.

The getDb() method efficiently caches the database connection using the null coalescing assignment operator, avoiding redundant lookups.


1454-1492: Efficient bulk update implementation for multi-tree operations.

The moveSubtreeToTargetTree() method effectively handles complex subtree movements with a single update query, properly updating all necessary attributes (left, right, depth, and tree).

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

♻️ Duplicate comments (2)
src/NodeContext.php (2)

27-33: Fix constructor body formatting.

The empty constructor body should be formatted as {} on the same line to comply with code style requirements.

 public function __construct(
     public readonly ActiveRecord $targetNode,
     public readonly string $operation,
     public readonly int $targetPositionValue,
     public readonly int $depthLevelDelta,
-) {
-}
+) {}

126-129: Fix type safety issue in getTargetDepth method.

The static analysis correctly identifies that casting mixed to int is unsafe. The method should validate the type before casting to ensure type safety.

 public function getTargetDepth(string $depthAttribute): int
 {
-    return (int) $this->targetNode->getAttribute($depthAttribute);
+    $depthValue = $this->targetNode->getAttribute($depthAttribute);
+    
+    if (!is_numeric($depthValue)) {
+        throw new \InvalidArgumentException("Depth attribute must be numeric, got: " . gettype($depthValue));
+    }
+    
+    return (int) $depthValue;
 }
🧹 Nitpick comments (1)
src/NodeContext.php (1)

35-117: Consider standardizing PHPDoc annotations across factory methods.

The factory methods use inconsistent PHPDoc annotations - some use @phpstan-var while others use @var. Consider standardizing to @phpstan-var for better static analysis support.

For consistency, update the remaining factory methods:

 public static function forInsertBefore(ActiveRecord $targetNode, string $leftAttribute): self
 {
-    /** @var int $leftValue */
+    /** @phpstan-var int $leftValue */
     $leftValue = $targetNode->getAttribute($leftAttribute);
 public static function forPrependTo(ActiveRecord $targetNode, string $leftAttribute): self
 {
-    /** @var int $leftValue */
+    /** @phpstan-var int $leftValue */
     $leftValue = $targetNode->getAttribute($leftAttribute);
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 5173b83 and 7a1a1ad.

📒 Files selected for processing (2)
  • src/NodeContext.php (1 hunks)
  • tests/support/stub/ExtendableNestedSetsBehavior.php (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/support/stub/ExtendableNestedSetsBehavior.php
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: terabytesoftw
PR: yii2-extensions/nested-sets-behavior#13
File: src/NestedSetsBehavior.php:145-145
Timestamp: 2025-06-29T11:22:41.839Z
Learning: The user terabytesoftw prefers to keep PRs focused and small, implementing enhancements in separate dedicated PRs rather than bundling multiple changes together.
🧬 Code Graph Analysis (1)
src/NodeContext.php (1)
src/NestedSetsBehavior.php (1)
  • NestedSetsBehavior (47-1504)
🪛 GitHub Check: mutation / PHP 8.4-ubuntu-latest
src/NodeContext.php

[failure] 128-128:
Cannot cast mixed to int.

🪛 GitHub Check: phpstan / PHP 8.4-ubuntu-latest
src/NodeContext.php

[failure] 128-128:
Cannot cast mixed to int.

🪛 GitHub Actions: ecs
src/NodeContext.php

[warning] 29-29: PhpCsFixer SingleLineEmptyBodyFixer: Method body should be empty on a single line. Run 'vendor/bin/ecs check --fix' to apply the fix.

⏰ Context from checks skipped due to timeout of 90000ms (13)
  • GitHub Check: phpunit-compatibility / PHP 8.2-windows-latest
  • GitHub Check: phpunit-compatibility / PHP 8.3-windows-latest
  • GitHub Check: phpunit-compatibility / PHP 8.3-ubuntu-latest
  • GitHub Check: phpunit-compatibility / PHP 8.2-ubuntu-latest
  • GitHub Check: phpunit-compatibility / PHP 8.4-windows-latest
  • GitHub Check: phpunit-compatibility / PHP 8.1-windows-latest
  • GitHub Check: phpunit-compatibility / PHP 8.1-ubuntu-latest
  • GitHub Check: phpunit / PHP 8.3-windows-latest
  • GitHub Check: phpunit / PHP 8.2-windows-latest
  • GitHub Check: phpunit / PHP 8.1-windows-latest
  • GitHub Check: phpunit / PHP 8.3-ubuntu-latest
  • GitHub Check: phpunit / PHP 8.1-windows-latest
  • GitHub Check: phpunit-compatibility / PHP 8.1-windows-latest
🔇 Additional comments (1)
src/NodeContext.php (1)

1-144: Excellent design for encapsulating node movement context.

The NodeContext class provides a clean, immutable value object that effectively encapsulates all necessary data for node movement operations. The static factory methods for each operation type (forAppendTo, forInsertAfter, etc.) provide clear, type-safe ways to create instances with appropriate positioning calculations.

Key strengths:

  • Immutable design with readonly properties
  • Operation-specific factory methods with clear naming
  • Proper calculation of targetPositionValue and depthLevelDelta for each operation
  • Type-safe accessor methods for target node properties

@terabytesoftw
Copy link
Member Author

@coderabbitai review

Copy link

coderabbitai bot commented Jul 2, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@terabytesoftw terabytesoftw changed the title feat: Enhance NestedSetsBehavior class to support multi-tree operations and improve node movement logic. feat: Introduce NodeContext class for improved node movement handling and refactor moveNode method to use context. Jul 2, 2025
@terabytesoftw
Copy link
Member Author

@coderabbitai review

Copy link

coderabbitai bot commented Jul 2, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@terabytesoftw terabytesoftw changed the title feat: Introduce NodeContext class for improved node movement handling and refactor moveNode method to use context. feat: Introduce NodeContext class for improved node movement handling and refactor beforeInsert, and moveNode method to use context. Jul 2, 2025
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)
src/NestedSetsBehavior.php (1)

381-393: Fix trailing comma formatting issue.

The pipeline failure indicates missing trailing commas in the multiline match expression. Add trailing commas to improve consistency and maintainability.

Apply this formatting fix:

     match (true) {
         $this->operation === self::OPERATION_APPEND_TO && $this->node !== null => $this->beforeInsertNodeWithContext(
-            NodeContext::forAppendTo($this->node, $this->rightAttribute)
+            NodeContext::forAppendTo($this->node, $this->rightAttribute),
         ),
         $this->operation === self::OPERATION_INSERT_AFTER && $this->node !== null => $this->beforeInsertNodeWithContext(
-            NodeContext::forInsertAfter($this->node, $this->rightAttribute)
+            NodeContext::forInsertAfter($this->node, $this->rightAttribute),
         ),
         $this->operation === self::OPERATION_INSERT_BEFORE && $this->node !== null => $this->beforeInsertNodeWithContext(
-            NodeContext::forInsertBefore($this->node, $this->leftAttribute)
+            NodeContext::forInsertBefore($this->node, $this->leftAttribute),
         ),
         $this->operation === self::OPERATION_MAKE_ROOT => $this->beforeInsertRootNode(),
         $this->operation === self::OPERATION_PREPEND_TO && $this->node !== null => $this->beforeInsertNodeWithContext(
-            NodeContext::forPrependTo($this->node, $this->leftAttribute)
+            NodeContext::forPrependTo($this->node, $this->leftAttribute),
         ),
         default => throw new NotSupportedException(
             'Method "' . get_class($this->getOwner()) . '::insert" is not supported for inserting new nodes.',
         ),
     };
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 74f5a6c and 8e5e264.

📒 Files selected for processing (4)
  • src/NestedSetsBehavior.php (12 hunks)
  • src/NodeContext.php (1 hunks)
  • tests/NestedSetsBehaviorTest.php (1 hunks)
  • tests/support/stub/ExtendableNestedSetsBehavior.php (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • tests/support/stub/ExtendableNestedSetsBehavior.php
  • src/NodeContext.php
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: terabytesoftw
PR: yii2-extensions/nested-sets-behavior#13
File: src/NestedSetsBehavior.php:145-145
Timestamp: 2025-06-29T11:22:41.839Z
Learning: The user terabytesoftw prefers to keep PRs focused and small, implementing enhancements in separate dedicated PRs rather than bundling multiple changes together.
🧬 Code Graph Analysis (1)
src/NestedSetsBehavior.php (3)
src/NestedSetsQueryBehavior.php (1)
  • getOwner (136-143)
src/NodeContext.php (9)
  • NodeContext (25-157)
  • forAppendTo (43-50)
  • forInsertAfter (62-71)
  • forInsertBefore (83-92)
  • forPrependTo (104-113)
  • getTargetPositionValue (139-142)
  • getDepthLevelDelta (115-118)
  • getTargetTreeValue (151-156)
  • getTargetDepth (129-132)
tests/TestCase.php (1)
  • getDb (40-43)
🪛 GitHub Actions: ecs
src/NestedSetsBehavior.php

[error] 379-395: PhpCsFixer: TrailingCommaInMultilineFixer detected missing trailing commas in multiline match expression. Run 'vendor/bin/ecs check --fix' to apply fixes.

⏰ Context from checks skipped due to timeout of 90000ms (15)
  • GitHub Check: phpunit / PHP 8.1-ubuntu-latest
  • GitHub Check: phpunit / PHP 8.4-windows-latest
  • GitHub Check: phpunit / PHP 8.1-windows-latest
  • GitHub Check: phpunit / PHP 8.2-windows-latest
  • GitHub Check: phpunit / PHP 8.2-ubuntu-latest
  • GitHub Check: phpunit / PHP 8.3-windows-latest
  • GitHub Check: phpunit / PHP 8.3-ubuntu-latest
  • GitHub Check: phpunit-compatibility / PHP 8.3-ubuntu-latest
  • GitHub Check: phpunit-compatibility / PHP 8.1-windows-latest
  • GitHub Check: phpunit-compatibility / PHP 8.4-windows-latest
  • GitHub Check: phpunit-compatibility / PHP 8.2-windows-latest
  • GitHub Check: phpunit-compatibility / PHP 8.3-windows-latest
  • GitHub Check: mutation / PHP 8.4-ubuntu-latest
  • GitHub Check: phpunit / PHP 8.2-windows-latest
  • GitHub Check: mutation / PHP 8.4-ubuntu-latest
🔇 Additional comments (10)
tests/NestedSetsBehaviorTest.php (1)

1604-1604: LGTM! Method signature properly updated to align with NodeContext refactoring.

The change from int|null $value to int $value correctly reflects the removal of nullable position parameters in the core behavior, which is part of the NodeContext class introduction. This enforces better type safety and aligns with the centralized movement logic improvements.

src/NestedSetsBehavior.php (9)

8-12: LGTM: Improved imports for new functionality.

The addition of RuntimeException, Connection, and explicit sprintf import appropriately supports the refactored node movement operations and improved database connection handling.


125-131: LGTM: Performance optimization with cached database connection.

Adding a cached Connection property with proper encapsulation improves performance by avoiding redundant database connection lookups throughout the behavior's operations.


261-274: LGTM: Improved type safety and clarity with NodeContext.

The refactoring to use explicit conditionals and NodeContext instances enhances type safety and makes the movement logic more maintainable. The early return pattern for root movement improves readability.


1094-1110: LGTM: Clean abstraction with NodeContext delegation.

The new method provides a clean interface for NodeContext-based insertion while maintaining the existing logic through delegation. This approach reduces code duplication and improves type safety.


1372-1381: LGTM: Well-structured factory method for movement contexts.

The createMoveContext() method provides a clean factory pattern for creating typed NodeContext instances based on operation type. The use of RuntimeException for unsupported operations is appropriate.


1394-1397: LGTM: Efficient database connection caching.

The cached getDb() method using null coalescing assignment optimizes performance by avoiding redundant connection lookups while maintaining clean encapsulation.


1437-1442: LGTM: Centralized tree value extraction.

The getTreeValue() method provides a consistent way to extract tree attribute values with proper null handling, improving maintainability across the behavior.


1463-1501: LGTM: Centralized subtree movement logic.

The moveSubtreeToTargetTree() method effectively centralizes the complex logic for moving subtrees between trees, performing all necessary attribute updates in a single bulk operation for optimal performance.


1070-1070: Position value is always non-null in NodeContext

NodeContext’s factory methods may pass a nullable value into its constructor, but getTargetPositionValue() always returns an int—defaulting to 0 when the stored value is null. Since beforeInsertNodeWithContext() always calls beforeInsertNode($context->getTargetPositionValue(), …), the signature change safely assumes a non-nullable int.

No further changes needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy