Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
If your module defines block_info dynamically, so removes blocks from it, the block table still has this entries.
Comment | File | Size | Author |
---|---|---|---|
#12 | 1227966_12.patch | 10.98 KB | BrockBoland |
#10 | drupal8.block-delete.10.patch | 12.6 KB | sun |
#9 | block-delete-1227966-9.patch | 5.02 KB | David_Rothstein |
#6 | block-delete-1227966-6.patch | 13.1 KB | David_Rothstein |
#1 | 1227966-block_rehash-delete.patch | 1.73 KB | dawehner |
Comments
Comment #1
dawehnerIn general this patch is expected to fail at the moment.
So what could be part of the problem: $bids is empty, if you have all code blocks in the database as well.
Additional:
This seems to be an indicator that the db_delete is never executed
Comment #2
dawehnerUpdate status
Comment #4
David_Rothstein CreditAttribution: David_Rothstein commentedGiving this a slightly more descriptive title.
This bug can be reproduced with a lot of modules that define dynamic blocks (examples include Views, Webform, and Media Gallery). If the view/webform/gallery goes away, the block still stays in the database and is rendered on the site if it returns something from hook_block_view(). But it doesn't appear at admin/structure/block so you can't disable it (although there seems to be a backdoor way to disable it by visiting admin/structure/block/manage/[MODULE]/[DELTA]/configure).
Here are some related issues:
#1273544: Media Gallery Block remains after deleting node
#1373360: Fatal error if optional Block module is not enabled
#1378354: Properly remove dependency of aggregator module on block module
Another way to come across this is to disable a module, then turn it back on again later. All the module's blocks will reappear on your site exactly where you left them. Actually in some ways that may be a feature (and at least for D7 backport we probably have to preserve that).
Comment #5
catchInfo hooks--
Bumping this up to major since it's causing problems in contrib, we already found a bug in aggregator trying to make up for it, and it's leaving the db in an inconsistent state.
Comment #6
David_Rothstein CreditAttribution: David_Rothstein commentedSo, it turns out there are a lot of places in core that try to poke their nose into {block} and {block_role}, whereas if _block_rehash() actually worked correctly they could leave it to do its job on its own.
This patch isn't fully tested, but it seems to work, and I think it's on the right track.
It contains a fair amount of cleanup though - all of it made possible by fixing _block_rehash() - so it's possible it could be broken up into two patches if necessary.
Comment #7
David_Rothstein CreditAttribution: David_Rothstein commentedNote that I incorporated the tests from #1 and expanded them a bit, although they could probably be expanded more (the {block_role} behavior is pretty tricky).
Comment #9
David_Rothstein CreditAttribution: David_Rothstein commentedIn some ways that test failure is expected. The Block module was basically treating its own dynamic blocks (a.k.a. custom blocks) differently than dynamic blocks provided by any other module, and then testing that special behavior...
That said, this is starting to get a bit more complicated than necessary, so I'm going to go ahead and split this into separate patches like I said above.
The attached patch only fixes deletion of the record in the {block} table, which is basically the major part of the bug. It does not fix deleting records in {block_role}, nor does it deal with any cleanup in other parts of the codebase that is possible as a result of this. Hopefully we can save that for a followup instead.
For now, let's see if this one passes tests.
Comment #10
sunActually, #6 works fine; merely needed some minor tweaking in the custom block delete form submit handler.
Along with that, I've simplified the code for determining whether block_role records can be deleted. We can execute multiple count queries there, because a) blocks rarely need to be deleted and b) the count query is fast, as it hits an index.
Comment #11
catchIt's nitpicking but I'm not sure about this check. If the block exists, then $block->body should always be set even if it's an empty string no? So can we just do if ($block) there?
This is going to delete blocks in the situation where a module conditionally defines a block based on the presence of another module that's currently disabled. I don't see a way out of this though.
Comment #12
BrockBoland CreditAttribution: BrockBoland commentedRe-created this patch manually against the current head of 8.x. I made a few tweaks:
return;
)block_flush_caches()
no longer exists; replaced withblock_rebuild
if (isset($block->body)) {
with simplyif ($block) {
as requested by catchThis hasn't been tested at all yet, it's just an update to the previous patch.
Comment #13
dawehnerI don't think we need this anymore with #1535868: Convert all blocks into plugins
Comment #14
kerasai CreditAttribution: kerasai commented#12: 1227966_12.patch queued for re-testing.
Comment #16
Gábor HojtsyMoving down to Drupal 7 based on #13.