The problem
Case:
- User “ZZZ” had 11 or more nodes (articles) which he is an author of.
- User “ZZZ” deleted with “Cancel the selected user account(s)” - “Delete the account and make its content belong to the Anonymous user.”
- Expected result: Nodes previously belong to “ZZZ” should belong to “Anonymous”.
Real result: Nodes previously belong to “ZZZ” disappeared.
Drupal log entry:
Warning: Parameter 5 to _node_mass_update_batch_process() expected to be a reference, value given in _batch_process() (line 252 of /.../core/includes/batch.inc).
Proposed resolution
While node count is less than 11 nodes are deleted in a loop; otherwise nodes deleted using batch.
For the time being temporary patch:
--- a/<html>core/modules/node/node.admin.inc (<b>Today 5:05:56 PM</b>)</html>
+++ b/<html><b>Current File</b></html>
@@ -33,7 +33,7 @@
function node_mass_update(array $nodes, array $updates, $langcode = NULL, $load = FALSE, $revisions = FALSE) {
// We use batch processing to prevent timeout when updating a large number
// of nodes.
- if (count($nodes) > 10) {
+ if (FALSE && count($nodes) > 10) {
$batch = array(
'operations' => array(
array('_node_mass_update_batch_process', array($nodes, $updates, $langcode, $load, $revisions))
Comment | File | Size | Author |
---|---|---|---|
#20 | 2688535-19.patch | 4.5 KB | alexpott |
#9 | interdiff.txt | 1.29 KB | amateescu |
#9 | 2688535-9.patch | 4.5 KB | amateescu |
#5 | 2688535-5.patch | 4.51 KB | amateescu |
#5 | 2688535-5-test-only.patch | 2.86 KB | amateescu |
Comments
Comment #2
olegiv CreditAttribution: olegiv commentedComment #3
cilefen CreditAttribution: cilefen commentedUnexpected data loss is critical priority.
Comment #4
amateescu CreditAttribution: amateescu for Pfizer, Inc. commentedThe problem is that
_node_mass_update_batch_process()
is missing a $langcode parameter, which should've been added in #1498674: Refactor node properties to multilingual.Comment #5
amateescu CreditAttribution: amateescu for Pfizer, Inc. commentedAnd with a test.
Comment #7
cilefen CreditAttribution: cilefen commentedWow, that was fast!
I think the coding standard is that parameters with default values must be at the end of the argument list.
Comment #8
cilefen CreditAttribution: cilefen commentedOh, I see, it's how the calling function works. It may not be possible to "fix" #7.
Comment #9
amateescu CreditAttribution: amateescu for Pfizer, Inc. commentedWell, the new parameter doesn't have to be optional, a default is provided by
node_mass_update()
anyway.Comment #10
xjmGreat work @amateescu, and thanks @olegiv for reporting this.
Can we add the parameter at the end as an optional one instead? Otherwise this is an internal API break, which makes it potentially disruptive for a patch release. And we definitely want to fix this in 8.0.x if we can, because data loss. The function is prefixed with an underscore so it's not a public API break, but this is the kind of "internal" API helper that contrib/custom code is prone to actually rely on.
Comment #11
xjmTo clarify #10, I think there would be a change within node_mass_update() as well just reordering the parameters in this line:
That way the
$langocde
could be added optionally. The downside is the parameters would be in a different order than the caller.If that doesn't make sense, this is the kind of issue we would actually break APIs for if needed, but best to avoid it if possible.
Comment #12
xjmHmmm OTOH maybe
$langcode
shouldn't be optional, if failing to provide it results in unexpected deletions of other content. So in that case a hard API break with a change record would actually be preferable, to ensure that any sites incorrectly using that helper do update it to receive the langcode correctly. Thoughts?Comment #13
catchHmm I'd probably go for #9 in 8.1.x and higher. Then the point about actively breaking things in 8.0.x to prevent data loss is a good one, so would go for it there too.
If you get a 500 error from some contrib/custom code that's not updated calling this function, that's not really worse than it unexpectedly deleting content. It should never be called during regular site operation - is pretty rare, so it's only going to break the mass update, not the regular functioning of the site.
Comment #14
amateescu CreditAttribution: amateescu for Pfizer, Inc. commentedI did consider making the new parameter optional and reorder the calling code, but I also think a hard break is preferable here for the reasons mentioned in #13.
Here's the change record: https://www.drupal.org/node/2692565
Comment #15
xjm@alexpott, @effulgentsia, @Cottser, @catch and I all agreed that this issue is critical because of the risk of data loss.
Comment #16
alexpottThe fix looks good and we have test coverage. And given the that we are already calling this with the param and all the functions are underscored I think adding the param makes sense.
Comment #18
catchComment #20
alexpottRerolled.
Comment #23
catchCommitted/pushed to 8.2.x and cherry-picked to 8.1.x. Thanks!
Comment #24
amateescu CreditAttribution: amateescu for Pfizer, Inc. commentedPublished the CR :)