Problem/Motivation
In #394268: DIE update_sql() DIE! a big cleanup of the update system was done which made it so update functions return a simple string (indicating a success message) rather than a complicated array like before.
However, some problems were introduced:
- We lost the ability for a single update function to return more than one message. There is already now code in core that tries to get around that via an ugly implode() - as shown (and fixed) in the attached patch. See also discussion in #774316: Remind users about new Drupal 8 features after migration from D7 which really could use that functionality.
- Similarly, an update function that gets called more than once (via a batch) has its initial return values ignored; only the last one is used.
- There is tons of code in update.php still designed to process the old method, and the result is that when update.php is finished we print a "list" of messages for each update function (using <li> tags) but the list can never have more than one element.
This patch cleans things up and restores the ability for an update function to return multiple messages either on a single pass or accumulated over multiple passes in a batch process.
Note: Drush probably requires some D7 changes as a result of this; I don't think that can be helped.
Steps to reproduce
Proposed resolution
TBA
Remaining tasks
Reroll patch
Add test, see #1 and #26
User interface changes
API changes
Data model changes
Release notes snippet
| Comment | File | Size | Author |
|---|
Issue fork drupal-870918
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #1
David_Rothstein commentedHere is some code I used while testing out this patch. We could possibly turn it into an actual test, if we want to try writing one:
Comment #2
David_Rothstein commentedRelated issue: #870922: Database query logs are never printed when update.php is run
Since database query results, which are stored in $ret['queries'], are already broken, this patch doesn't attempt to deal with that part of the $ret array at all. I think it is better to fix this first and then do a followup in the other issue.
Comment #3
jacineYou rock! Subscribing for now.
Comment #4
yched commentedThis looks like a great cleanup.
I'm a little worried at what exactly the array_merge_recusrive() will do.
If I read the patch correctly, $ret is now an array with two entries, 'messages', 'queries'.
'messages' is an array of flat strings, so array_merge_recusrive() should be OK there.
I'm not sure about 'queries', though. If each logged query is itself an array, we don't want deep merging.
One detail about the test update func in #1 : you'd rather use a variable_set() / variable_get() mechanism rather than a static for $steps. A static will break if batch API interrupts processing after step N, and step N+1 is done in a subsequent HTTP request.
Comment #5
David_Rothstein commentedI think 'queries' is a numerically-indexed array, so even though each element is itself an array, the merging won't go any deeper than that. I'm not 100% positive, though, and array_merge_recursive() often trips me up :)
It might at least be worth a code comment there. However, #870922: Database query logs are never printed when update.php is run may remove this anyway.
Comment #6
David_Rothstein commentedRerolled the patch for Drupal 8.
Since #870922: Database query logs are never printed when update.php is run has been committed, I was able to avoid using array_merge_recursive() and simplify this patch a couple other ways also.
Comment #7
yched commentedStill is a very nice cleanup. Code looks good.
One minor nitpick : the $ret array in update_do_one() ends up as $results in update_results_page(). $ret being a sad remnant from the old hook_update_N() return format, could we simply rename it $result all the way ?
Comment #8
star-szrRerolled against D8 HEAD. No code changes from #6.
Comment #9
yched commentedThanks for the reroll, @Cottser.
As mentioned in #7, please just rename the $ret variable in update_do_one() to $results. Then this is RTBC.
Comment #10
star-szr@yched - I've made that revision, here's an updated patch and interdiff.
Comment #11
yched commentedThanks !
Comment #12
star-szrShould this have tests?
Comment #13
catchYes, I think it should.
Comment #25
quietone commentedI am wondering if this was fixed in #2250119: Run updates in a full environment. Looks like \Drupal\system\Controller\DbUpdateController::results handles multiple messages from a module.
Can someone confirm?
Comment #26
darvanenI used a slightly modified version of the test update in #1:
And the output was (drumroll please):
Looks like this is still an issue.
Comment #27
quietone commented@darvanen, thank you!
Did a wee update to the Issue Summary.
Comment #28
bhanu951 commentedComment #30
bhanu951 commentedRerolled the Patch 870918-10.patch for 10.1.x branch. Pls review.
Comment #31
phenaproximaThanks for switching to a merge request.
However, this patch is fully ten years old - it predates Drupal 8! -- and looks like it's full of out-of-scope changes. We probably need to restart this from scratch.
Comment #32
phenaproximaHiding patches in favor of the merge request.