How to avoid infinite loop when extending a model which use the HasSettings trait #112
felahdab
started this conversation in
Show and tell
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Hi everyone.
First: thank you to all developer and contributors to this package which is very well done and practical.
I want to share a problem into which I ran with this package. It doesn't really qualify as a bug. It's not about a feature request neither.
Long story short:
In a project I am working on, I have included this package and I am using the nWidart/laravel-modules package.
In order to separate concerns, I have models from different modules which extend models from other modules or from the base namespace (
App\Models
).I faced the following situation:
App\Models\User
usesHasSettingsTable
(and thereforeHasSettings
trait also).Modules\HR\Entities\Person
extends the User moduleWhen doing that without more precaution, I faced an infinite loop and therefore a sudden and silent application crash, when calling any method on the Person model resulting in a query having to be built and executed.
This infinite loop was coming from the
HasSettings
trait way of overriding the__call
method in order to catch the$invokeSettingsby
property when it is set.In particular, in that method, the use of
call_user_func(get_parent_class($this) . '::__call', $name, $args);
triggers the infinite loop.I presume that since the Person model already extends the User model, but doesn't override the
__call
method which is already a method ofget_parent_class($this)
, the call_user_func is actually calling itself.Even if it made itself visible when building a query from the inherited model, many other uses of that same model would have resulted in the infinite loop.
I am unsure as to why the
call_user_func
syntax was used in order to forward the calls to parent classes inHasSettings
.Changing this line to
parent::__call($name, $args)
seemed to work equally well (but I didn't go thru complete tests and might have missed something).But I didn't want to change the module code so I resorted to another way of resolving this issue without having to change the HasSettings code :
I simply override the __call method in the Person model like so:
And by doing just that, since I make sure that the
HasSettings __call
method is called at theUser
level of inheritance, the infinite loop doesn't happen.In conclusion:
__call
method.parent::__call($name, $args)
would do equally well for the laravel-model-settings package, which I leave to the developpers to figure out.Regards.
Beta Was this translation helpful? Give feedback.
All reactions