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\UserusesHasSettingsTable(and thereforeHasSettingstrait also).Modules\HR\Entities\Personextends 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
HasSettingstrait way of overriding the__callmethod in order to catch the$invokeSettingsbyproperty 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
__callmethod 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_funcsyntax 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 __callmethod is called at theUserlevel of inheritance, the infinite loop doesn't happen.In conclusion:
__callmethod.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