Problem/Motivation

The setting block_classes_stored only retains the class(es) from the most recently saved block.

Steps to reproduce

On a fresh install of block_class 2.0 branch:

  1. Visit any block config form and add one or more classes (e.g. class-1 and class-2). Save the block.
  2. Visit a different block form and add a different class (e.g. class-3). Save the block.
  3. Visit any block and click the 'Click here to see all the classes used' link.

Only class-3 will appear in the list.

Proposed resolution

Fix BlockClassHelperService::blockClassPreSave() where $current_block_classes is incorrectly merged with itself, rather than $block_classes_stored.

Remaining tasks

  1. Patch
  2. Review
  3. Commit
Command icon 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

justcaldwell created an issue. See original summary.

justcaldwell’s picture

Status: Active » Needs review
justcaldwell’s picture

Priority: Normal » Major

Elevating to 'Major' since this does cause some data loss. If that last block saved has no classes configured at all, the store class list will be wiped entirely, causing autocomplete to fail, list of classes use will be blank, etc.

renatog’s picture

Priority: Major » Minor
Status: Needs review » Needs work

Hello @justcaldwell I hope you're doing well

First of all, thank you so much, good catch.

I totally agree merging that but just to confirm some points:

Visit any block and click the 'Click here to see all the classes used' link

Elevating to 'Major' since this does cause some data loss

Just to clarify, the link Click here to see all the classes used uses another config stored as json, it's not the block class saved in your blocks.

In other words, this JSON can be "empty" for example but the classes stored in "blocks" will continue existing, because the class in blocks is saved in thirdPartySettings of each block, and the link 'Click here to see all the classes used' uses another JSON stored in config->set you, know?!

For this reason above the "list of used classes" is informative only and isn't the same of classes in blocks so it'll not impact any usage. So I'm updating the Priority to "Minor". Please can you confirm if the classes in blocks are being removed? If is confirmed please let me know and we can increase again

Second point, apart from that I'm ok merging that. But the MR isn't able to merged since says that needs a rebase: https://git.drupalcode.org/project/block_class/-/merge_requests/7

So I'm updating the status to Needs Work

Merge blocked: the source branch must be rebased onto the target branch.

Do you mind updating the MR, please?

Or if you prefer, you can create a patch as well

justcaldwell’s picture

StatusFileSize
new676 bytes

Hi @RenatoG. Hope you're well, too. I really appreciate all the new functionality in the 2.x branch!

Just to be clear, I was using "Click here to see all the classes..." as a quick way to confirm the bug. I didn't intend to imply the the classes for a specific block would be lost. Just that the data from previously saved classes might be wiped from block_classes_stored. I'm probably off base, but I consider loss of config data loss, too.

That said, gitlab still seems to be doing odd things, so a patch is attached. Cheers!

justcaldwell’s picture

Status: Needs work » Needs review
justcaldwell’s picture

One related potential problem that just occurred to me: I don't currently see anything that prunes the list of stored classes to what is actually in use somewhere.

For example, say I add 'backgrind-blue' to a block and save it. I immediately realize my mistake, go back and change it to 'background-blue'. Both 'backgrind-blue' and 'background-blue' will continue to appear in the list of classes and in autocomplete results.

That would be it's own issue if it's a concern. Same is true for attributes.

justcaldwell’s picture

Priority: Minor » Normal
StatusFileSize
new69.01 KB

An interesting side effect of this bug is causing a problem during config sync for us. Probably a bit of an edge case, but documenting here in case anyone else runs into this.

We use Configuration Split to (among other things) enable Masquerade and the block it provides in our dev/local environments only. There is no block class configured for the masquerade block.

When we migrated from Block Class 8x-1.x to 2.x, the update code nicely examined all our existing blocks, and populated block_classes_stored accordingly. The updated code and config was deployed to production, and all was good!

Now, though, when we attempt to import production config to a local environment, all appears to succeed, but actually block_class.settings is immediately out-of-sync. Subsequent config imports unexpectedly indicate that block_class.settings has updates to import. Exporting config reveals that block_classes_stored is now empty in the active config.

Screenshot of active vs staged config immediately after import.

Essentially, when config is imported, the masquerade block becomes enabled, and blockClassPreSave() is invoked. Since the newly-enabled block has no block class, that empty value is saved to block_classes_stored, wiping it's previous class list, and making the active config immediately out-of-sync with the staged config.

The patch resolves the issue.

justcaldwell’s picture

StatusFileSize
new4.25 KB
new3.59 KB

While testing the patch in the context of the issue I described in #9, I realized the current code is storing empty values. The attached patch addresses that.

The interdiff is next to useless—the change is essentially to wrap all the class processing in a conditional:

// Only process non-empty values.
if (!empty($block_classes)) {
  // class processing move here...
}
renatog’s picture

Issue tags: +Needs manual testing

Thanks a lot for your contributions, we really appreciate

Let's do a manual validation on this. So putting some tags "needs manual testing" to see if someone can help us on this

renatog’s picture

Issue tags: -Needs manual testing
StatusFileSize
new4.04 KB
new579 bytes

@justcaldwell I tested and the patch on #10 worked for me

I also did small fixes where was return; and skipping unnecessary. The new patch is attached, do you mind verifying if works for you, please?

Thank you so much, have a great weekend

renatog’s picture

Please discard #12. I saw that one part that was fixing on this patch were fixed at #3320580: Attribute values are not processed if id is empty and the other was being fixed at #3320583: attributes_inline setting only retains attributes from most recently saved block

renatog’s picture

Status: Needs review » Needs work

We merged #3320580: Attribute values are not processed if id is empty and #3320583: attributes_inline setting only retains attributes from most recently saved block and now if we apply the patch #10 and following the steps on Issue summary it's not working:

Get the clean dev-branch 2.0.x and apply the patch #10

  1. Visit any block config form and add one or more classes (e.g. class-1 and class-2). Save the block.
  2. Visit a different block form and add a different class (e.g. class-3). Save the block.
  3. Visit any block and click the 'Click here to see all the classes used' link.

Any class appear in the list

renatog’s picture

Status: Needs work » Needs review
StatusFileSize
new3.63 KB
new436 bytes

I found the reason. After $config->set('block_classes_stored', $block_classes_to_store); we weren't saving the config, and in the other cases down in the code the config->save will be called only when necessary. So if we don't save the config after set "block_classes_stored" there is a risk to don't have other config save and this config won't be saved.

Just saving the config it worked well

  • f7ec46d committed on 2.0.x
    Issue #3320529 by justcaldwell, RenatoG: block_classes_stored setting...
renatog’s picture

Status: Needs review » Fixed

Moved to the dev branch. Thanks @justcaldwell

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

justcaldwell’s picture

Hi @RenatoG! Looks like this change (as well as #3320583: attributes_inline setting only retains attributes from most recently saved block and #3320580: Attribute values are not processed if id is empty) didn't make it into 2.0.8? Do you have a timeline for a next release?

renatog’s picture

Done @justcaldwell

The new release 2.0.9 is available with these fixes: https://www.drupal.org/project/block_class/releases/2.0.9

Thanks a lot for your contribution

justcaldwell’s picture

Thanks @RenatoG -- much appreciated!