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