You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The context for this one is that I have some logic to create missing (Versioned) DB records, and this can be triggered by author actions, but also by frontend user requests (if for some reason the records were missing for a frontend user's request).
What I noticed was that if a frontend user is browsing the website (in a LIVE stage), then my DB records are (effectively) published even though I was only ever calling write() on them.
This isn't necessarily problematic, but it was a bit unexpected for me, so I thought I should raise it, even if just for visibility for others.
Browsing to a Page that has this block with ?stage=Stage in my URL has the result that I was expecting. The DataObject is in "draft only".
MyVersionedDataObject
ID
ClassName
LastEdited
Created
Version
Title
1
App\Models\MyVersionedDataObject
2022-11-30 10:13:44
2022-11-30 10:13:44
1
Test DO
MyVersionedDataObject_Live
ID
ClassName
LastEdited
Created
Version
Title
MyVersionedDataObject_Versions
ID
RecordID
Version
WasPublished
WasDeleted
WasDraft
AuthorID
PublisherID
ClassName
LastEdited
Created
Title
1
1
1
0
0
1
1
0
App\Models\MyVersionedDataObject
2022-11-30 10:13:44
2022-11-30 10:13:44
Test DO
Browsing with ?stage=Live
This is where things got "unexpected" for me. Browsing the same Page/Block, but now the user is in a LIVE reading mode.
MyVersionedDataObject
ID
ClassName
LastEdited
Created
Version
Title
1
App\Models\MyVersionedDataObject
2022-11-30 10:17:24
2022-11-30 10:17:24
1
Test DO
MyVersionedDataObject_Live
ID
ClassName
LastEdited
Created
Version
Title
1
App\Models\MyVersionedDataObject
2022-11-30 10:17:24
2022-11-30 10:17:24
1
Test DO
MyVersionedDataObject_Versions
ID
RecordID
Version
WasPublished
WasDeleted
WasDraft
AuthorID
PublisherID
ClassName
LastEdited
Created
Title
1
1
1
1
0
1
1
1
App\Models\MyVersionedDataObject
2022-11-30 10:17:24
2022-11-30 10:17:24
Test DO
Unit test set up
We can simulate the same thing in unit tests / etc with something like this:
Versioned::withVersionedMode(function (): void {
Versioned::set_stage(Versioned::LIVE);
$record = MyVersionedDataObject::create();
$record->write();
// isPublished() returns true, but I was expecting false since I haven't called publishSingle/Recursive()Debug::dump($record->isPublished());
// I can also re-fetch the record, and that is still published
});
Solution
Well, I'm not sure. I guess it depends if this is expected behaviour or not.
At the very least, I do think that this behaviour will be unexpected to some developers (it certainly was to me). This probably comes down to a lack of understanding on how write() and publishSingle/Recursive() work. I now understand that publish..() is actually just setting the reading mode to LIVE and then performing a write(), and with that knowledge I think that this behaviour makes sense. I think though that most of us come into this thinking that since there are two distinct methods, that write() is for DRAFT and publish...() is for LIVE.
My takeaway from this (for now at least) is that I actually need to be far more aware of the context in which my code might be triggered. If I believe that my code can be triggered within a LIVE stage, then I actually need to wrap any write()/publish() actions within the DRAFT stage.
EG:
Versioned::withVersionedMode(staticfunction () use ($record): void {
Versioned::set_stage(Versioned::DRAFT);
$record->write();
});
The text was updated successfully, but these errors were encountered:
I think this is at least intended behaviour, even if it’s a bit unexpected - as far as I remember ->write() has always performed operations on the current stage. I think the docs here are actually a bit misleading too which doesn’t help:
When you call the write() method on a versioned DataObject, this will transparently create a new version of this DataObject in the Stage stage.
That only happens if the current stage is set to Stage, not Live (as you’ve found out!). We also have a writeToStage() method which only gets a quick mention further down the doc, not sure why that’s categorised as a “low-level” method
Hi team,
The context for this one is that I have some logic to create missing (
Versioned
) DB records, and this can be triggered by author actions, but also by frontend user requests (if for some reason the records were missing for a frontend user's request).What I noticed was that if a frontend user is browsing the website (in a
LIVE
stage), then my DB records are (effectively) published even though I was only ever callingwrite()
on them.This isn't necessarily problematic, but it was a bit unexpected for me, so I thought I should raise it, even if just for visibility for others.
Set up
MyVersionedDataObject:
MyBlock.php:
Maybe not the most elegant set up, but I just had one of my Blocks write a new record whenever I request
$Title
in the template.MyBlock.ss:
Tables
MyVersionedDataObject
MyVersionedDataObject_Live
MyVersionedDataObject_Versions
Browsing with
?stage=Stage
Browsing to a Page that has this block with
?stage=Stage
in my URL has the result that I was expecting. TheDataObject
is in "draft only".MyVersionedDataObject
MyVersionedDataObject_Live
MyVersionedDataObject_Versions
Browsing with
?stage=Live
This is where things got "unexpected" for me. Browsing the same Page/Block, but now the user is in a
LIVE
reading mode.MyVersionedDataObject
MyVersionedDataObject_Live
MyVersionedDataObject_Versions
Unit test set up
We can simulate the same thing in unit tests / etc with something like this:
Solution
Well, I'm not sure. I guess it depends if this is expected behaviour or not.
At the very least, I do think that this behaviour will be unexpected to some developers (it certainly was to me). This probably comes down to a lack of understanding on how
write()
andpublishSingle/Recursive()
work. I now understand thatpublish..()
is actually just setting the reading mode toLIVE
and then performing awrite()
, and with that knowledge I think that this behaviour makes sense. I think though that most of us come into this thinking that since there are two distinct methods, thatwrite()
is forDRAFT
andpublish...()
is forLIVE
.My takeaway from this (for now at least) is that I actually need to be far more aware of the context in which my code might be triggered. If I believe that my code can be triggered within a
LIVE
stage, then I actually need to wrap anywrite()
/publish()
actions within theDRAFT
stage.EG:
The text was updated successfully, but these errors were encountered: