Skip to content
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

Fix settings model #1071

Closed
wants to merge 2 commits into from
Closed

Fix settings model #1071

wants to merge 2 commits into from

Conversation

mjauvin
Copy link
Member

@mjauvin mjauvin commented Feb 27, 2024

No description provided.

@mjauvin mjauvin added maintenance PRs that fix bugs, are translation changes or make only minor changes needs review Issues/PRs that require a review from a maintainer labels Feb 27, 2024
@mjauvin mjauvin added this to the 1.2.5 milestone Feb 27, 2024
@mjauvin mjauvin self-assigned this Feb 27, 2024
@mjauvin
Copy link
Member Author

mjauvin commented Feb 27, 2024

The alternative is to fix it at the Database/Model level with a code snippet like this:

diff --git a/src/Database/Model.php b/src/Database/Model.php
index 40390596..2b56cadf 100644
--- a/src/Database/Model.php
+++ b/src/Database/Model.php
@@ -1378,6 +1378,12 @@ public function setAttribute($key, $value)
 
         $result = parent::setAttribute($key, $value);
 
+        if ($this->hasSetMutator($key)) {
+            if ($_value = parent::getAttributeValue($key)) {
+                $value = $_value;
+            }
+        }
+
         /**
          * @event model.setAttribute
          * Called after the model attribute is set
diff --git a/src/Halcyon/Model.php b/src/Halcyon/Model.php
index f51c3ac4..3322dd41 100644
--- a/src/Halcyon/Model.php
+++ b/src/Halcyon/Model.php
@@ -786,6 +786,8 @@ public function setAttribute($key, $value)
             // post processing logic when an attribute is set with explicit mutators. Returning from the mutator
             // call will also break method chaining as intended by returning `$this` at the end of this method.
             $this->{$method}($value);
+
+            $value = array_get($this->attributes, $key);
         }
         else {
             $this->attributes[$key] = $value;

@bennothommo
Copy link
Member

@mjauvin any chance we can have a unit test for this scenario? Best to cover it while we're fixing it.

@bennothommo bennothommo added Status: Revision Needed and removed needs review Issues/PRs that require a review from a maintainer labels Feb 28, 2024
@mjauvin
Copy link
Member Author

mjauvin commented Feb 28, 2024

@mjauvin any chance we can have a unit test for this scenario? Best to cover it while we're fixing it.

Sure. Any feedback on my comment for doing this on the base Model ?

@bennothommo
Copy link
Member

@mjauvin thank you for asking that question - it allowed me to deep-dive another hell hole 😂.

TL;DR: Let's can this fix, there's a better fix.

The parent Laravel model setAttribute() method already checks for the presence of a mutator, and returns whatever the mutator returns as the result. We, in turn, return the result of the parent setAttribute() method as the result of our own method. However, this result isn't passed on to the model.setAttribute event in any way - we only pass the key and the value, which besides being trimmed, or JSON encoded, or affected in some way by the model.beforeSetAttribute event, is untouched.

I would say the reason for that is because mutators, by design, aren't limited to just mutating the given attribute. For example, you could set up a mutator that takes a start date that automatically mutates the end date to a month later.

So I would suggest that perhaps, a more robust fix to the main Model class would be to in fact call $this->getAttribute() when firing the model.setAttribute event.

Instead of:

$this->fireEvent('model.setAttribute', [$key, $value]);

It should perhaps be:

$this->fireEvent('model.setAttribute', [$key, $this->getAttribute($key)]);

I'm not sure of whether this will break something - if so, maybe it could be added as a third parameter for the event, and the Settings model could be updated to suit.

@bennothommo
Copy link
Member

bennothommo commented Mar 5, 2024

@mjauvin I've proposed an alternate fix here (#1080) to shore up the API and incorporate @LukeTowers concerns about the event change, in case we don't end up changing the event.

@bennothommo bennothommo closed this Mar 5, 2024
@mjauvin
Copy link
Member Author

mjauvin commented Mar 5, 2024

Frankly, I don't like this.

@bennothommo
Copy link
Member

@mjauvin may I ask what is the issue with it?

@mjauvin
Copy link
Member Author

mjauvin commented Mar 5, 2024

I think fixing the event is the best way to resolve the issue everywhere. That event makes no sense the way it is now.

@bennothommo bennothommo deleted the fix-settings-model branch August 13, 2024 01:48
@mjauvin mjauvin removed this from the 1.2.5 milestone Dec 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
maintenance PRs that fix bugs, are translation changes or make only minor changes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants