-
Notifications
You must be signed in to change notification settings - Fork 11.3k
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
[10.x] Fix Macroable trait conflicting with class magic methods #54886
Closed
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
…odels When an Eloquent model uses the Macroable trait, core functionality breaks due to conflicting magic method implementations. Macroable's `__call` and `__callStatic` override Eloquent's methods, causing exceptions when internal methods aren't macros. This test demonstrates two failures: - Static methods like `create()` fail with `BadMethodCallException`. - Query methods that depend on `hydrate()` also fail with `BadMethodCallException`. This issue affects modular applications that extend Eloquent models dynamically.
…ic methods This fixes an issue where adding the Macroable trait to Eloquent models breaks core functionality. The conflict arises because both Eloquent's Model class and Macroable implement `__call` and `__callStatic`, and PHP gives precedence to the trait's implementation. Issue details: - Methods like `create()`, `find()`, and `hydrate()` were intercepted by Macroable. - Since these weren't registered as macros, `BadMethodCallException` was thrown. Fix implemented: - Updated Macroable's magic methods to check if the parent can handle the call before throwing an exception. - Ensures compatibility between dynamic macros and Eloquent's method resolution. Impact: - Prevents breaking core Eloquent functionality in modular applications. - Allows extending models dynamically while preserving Eloquent behavior. Tests: - Added test cases to validate that both Eloquent methods and custom macros work.
…rovider Updated the Macroable trait test to ensure compatibility with macros registered via a ServiceProvider. This improves test coverage by validating that macros added in a ServiceProvider are recognized by Eloquent models.
Reformatted the test files to conform to Laravel Pint's coding style standards. This ensures consistency across the codebase and improves readability.
…heritance Updated method resolution by replacing `method_exists()` with `is_callable()` to better support multi-level inheritance. This ensures that overridden methods in parent classes are properly detected. Additional improvements: - Updated return type checking for better type safety.
Reformatted the test files to conform to Laravel Pint's coding style standards. This ensures consistency across the codebase and improves readability.
…gration checks Refactored the logic by replacing explicit integration error checks with a `try-catch` block. This simplifies error handling and improves maintainability.
Fixed PHPStan errors related to parent method calls in the `Macroable` trait by improving method existence checks and adding PHPStan ignore directives. Changes include: - Checked each parent class for `__call` and `__callStatic` before invoking them. - Ensured parent methods are only called if they exist. - Added PHPStan ignore directives for specific error types: - `class.noParent` for cases where the class has no parent. - `staticMethod.notFound` for cases where the parent doesn't have the method.
Laravel Framework 10.x no longer receiving bug fixes or security fixes. |
No chance to get this applied? @crynobone |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Problem
Adding the
Macroable
trait to a class that already implements__call
and__callStatic
breaks core functionality. This is especially problematic forEloquent models, where methods like
create()
andhydrate()
fail, butit affects any class using these magic methods.
Reproduction: A full demonstration of this issue can be found at
https://github.com/rsd/macroable-test.
Root Cause
Macroable
implement__call
and__callStatic
.Macroable
does not attempt to delegate to the parent class.Solution
Updated
Macroable
's magic methods to check if the parent class can handlethe method before throwing an exception. This ensures:
Testing
work together correctly.
Impact
This fix is critical for:
Macroable
.Macroable
alongside magic methods.Without this fix, developers must choose between using
Macroable
or keepingthe class’s original magic method functionality. This is especially problematic
for modular Laravel systems, where extending models dynamically is essential.