Problem/Motivation

This problem can be reproduced when using panels, page manager and facets.

If a facet is being used on a page variant and gets deleted, the page variant is deleted too.

Steps to reproduce:

  • create a indexed view
  • create a facet for that view
  • create a page variant
  • add the facet block to it
  • delete the facet

Current result:

The page variant is completely deleted.

Expected result:

The page variant remains but the facet block is removed from "Content".

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

rmarques created an issue. See original summary.

borisson_’s picture

Issue tags: +Needs tests

Your report here makes it seem that #2860578: Support for blocks in panels is not needed? I haven't tried this yet but when we fix this, we should also add a test that uses the panels module

rutiolma’s picture

@borisson_ that's right, it's already possible to include facets in panels, either using latest stable versions or dev's.

borisson_’s picture

Issue tags: +beta blocker

This is a bug that affects the data integrity, so we should do this before we tag the first beta.

borisson_’s picture

@rmarquest, thanks for #3!

I haven't tried this yet but when we fix this, we should also add a test that uses the panels module

I've actually been thinking about this more and we get requests about panels quite often but I'm a little bit hesitant to add panels-specific tests, while it would be nice to have test-coverage, I haven't used panels in d8 yet and have no idea how it works.

So that task is daunting. Not sure if we should add page_manager or panelizer as well.
I'm afraid to add code that I don't understand. I'll have to ask some of the other maintainers if they use/understand panels well enough to know what to do here.

I'll try to get a hold of the panels team to see if this is something that should be fixed on our end or on theirs.

dcam’s picture

I think that this is a problem with Page Manager. I also have a page that is displaying facet blocks via Panels. I checked the page variant's configuration. It lists all of the facet blocks as configuration dependencies.

I'd love to verify this issue personally, but I can't right now. The one site I have with this configuration set up is being used this weekend for demo purposes. People would be mad at me if I broke it.

I don't know everything about config dependencies, but generally when a config dependency is deleted then all of its dependent configurations get deleted too. I'm pretty sure that's why this is happening. Based on what I know, Page Manager needs to react to the config delete event in order to remove the facet block (or any other block) from its configuration in a non-destructive manner. I looked and it doesn't.

One of the Page Manager maintainers is in my DUG. I'll ask him about this at this month's meeting. I think you can probably ignore this issue though.

borisson_’s picture

I don't know everything about config dependencies, but generally when a config dependency is deleted then all of its dependent configurations get deleted too. I'm pretty sure that's why this is happening. Based on what I know, Page Manager needs to react to the config delete event in order to remove the facet block (or any other block) from its configuration in a non-destructive manner. I looked and it doesn't.

This is what I figured as well. I hope that we can just close this issue instead of actually having to write test-coverage and code to fix this.

One of the Page Manager maintainers is in my DUG. I'll ask him about this at this month's meeting. I think you can probably ignore this issue though.

That would be awesome. I tried tweeting about this: https://twitter.com/Borisson/status/866710249729806337 https://twitter.com/Borisson/status/855747360420491265 but haven't gotten an answer yet.

If it turns out that we do have to fix this in our own code, I'm happy to give it a try but I'd love to get at least feedback on what modules we should use on our side to get accurate testcoverage.

Thanks @dcam!

dcam’s picture

@EclipseGc is the person from my DUG. I'll get an answer from him.

dcam’s picture

Title: Page variants get deleted when Facet is deleted » Extend FacetDeleteConfirmForm from EntityDeleteForm
Status: Active » Needs review
FileSize
1.48 KB

I talked to @EclipseGc last night. I confirmed the bug while talking to him (which I should have done beforehand). When I did, I realized that the facet delete form doesn't warn the user that other dependent config entities will be deleted too. So that's bad. Anyway, my page variant was deleted along with the facet due to the dependency. EclipseGc agreed that it's on Page Manager to non-destructively remove blocks from its configuration, but we agreed that it's on Facets to warn people that it's about to happen.

After the meeting I looked into what gives most config delete forms the list of other dependencies that will be deleted. It's done by extending \Drupal\Core\Entity\EntityDeleteForm instead of EntityConfirmFormBase. Turns out I did the same thing earlier this week when I created a custom config entity for the first time. The official docs say that EntityConfirmFormBase should be extended. I wonder if you (or whoever wrote this class) was reading the same thing. I'm going to go see about editing that doc after this.

Anyway, I've attached a patch. Most of the existing class can be removed because it just duplicates what EntityDeleteForm does. Check it out. Let me know if I need to add a test for this. I didn't see a pre-existing one that I needed to modify, but I may have missed it.

borisson_’s picture

Issue tags: -Needs tests
FileSize
1.03 KB
2.49 KB

Thanks! Good to know all that information. I changed the test so that we now have explicit coverage.

dcam’s picture

There may be an alternative. I think you can change the facet entity annotation and set the delete form directly to EntityDeleteForm. Then you could have one less class in the module.

The caveat is that the change requires you to have an entity.facets_facet.collection route defined because that's what EntityDeleteForm uses as its cancel URL, so facets.overview would have to be renamed. That means changing ~11 places in the module that refer to the facets.overview route. That could also be disruptive for anyone else who might be using the facets.overview route, but this is still in alpha, so maybe disruptive changes are ok. I don't know. It's up to you. I can write a patch for it if you're interested.

borisson_’s picture

There may be an alternative. I think you can change the facet entity annotation and set the delete form directly to EntityDeleteForm. Then you could have one less class in the module.

Yes, deleting code is the best thing!

The caveat is that the change requires you to have an entity.facets_facet.collection route defined because that's what EntityDeleteForm uses as its cancel URL, so facets.overview would have to be renamed. That means changing ~11 places in the module that refer to the facets.overview route. That could also be disruptive for anyone else who might be using the facets.overview route, but this is still in alpha, so maybe disruptive changes are ok. I don't know. It's up to you. I can write a patch for it if you're interested.

This issue has been marked as a beta blocker for weeks, so it was to be expected that this could lead to potential breaks. I don't think this is very dispruptive either, this is only important for others who've written code that links to the facet overview - and I don't know of anyone doing that (in contrib at least).

borisson_’s picture

Status: Needs review » Needs work

Needs work based on #12.

dcam’s picture

As I ran a find and replace for the old route name I realized that the Facets Summary delete form has the same problem. I'm editing it as well and trying to add a test. I don't think the summary delete form class can be removed entirely though because the summaries won't have their own collection route. In that case, the class will remain and only override the getCancelUrl() method.

dcam’s picture

FileSize
2.83 KB
9.15 KB

I added a new test for facet summary block deletion.

dcam’s picture

Status: Needs work » Needs review

Sorry. Status.

The last submitted patch, 15: 2861541-15--tests-only.patch, failed testing. View results

borisson_’s picture

Status: Needs review » Reviewed & tested by the community

Looks great! Thanks.

dcam’s picture

Title: Extend FacetDeleteConfirmForm from EntityDeleteForm » Use EntityDeleteForm for entity deletion

The title wasn't representative of the suggested change anymore since the Facet delete form was removed entirely. Though it's kind of redundant now. It won't bother me if you change it to something else.

  • borisson_ committed 5e4be67 on 8.x-1.x authored by dcam
    Issue #2861541 by dcam, borisson_: Use EntityDeleteForm for entity...
borisson_’s picture

Status: Reviewed & tested by the community » Fixed

Committed and pushed.

Status: Fixed » Closed (fixed)

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

gun_dose’s picture

It seems that problem is still actual. I use latest dev-version of facets and when I delete facet, page variant is deleted too. May be solution must be more complex and more obvious, something like this:

if (\Drupal::moduleHandler()->moduleExists('page_manager')) {
 $pageVariantStorage = \Drupal::entityTypeManager()->getStorage('page_variant');
 $block_id = 'facet_block:' . $this->entity->id();
 $page_variants = $pageVariantStorage->loadMultiple();
 /** @var \Drupal\page_manager\Entity\PageVariant $page_variant */
 foreach ($page_variants as $page_variant) {
  $settings = $page_variant->get('variant_settings');
  if (!isset($settings['blocks'])) {
    continue;
  }
  foreach ($settings['blocks'] as $uuid => $block) {
    if ($block['id'] !== $block_id) {
      continue;
    }
    unset($settings['blocks'][$uuid]);
    $page_variant->set('variant_settings', $settings);
    $page_variant->save();
  }
}
 $this->entity->delete();

This must be placed in FacetDeleteConfirmForm in submitForm method.

borisson_’s picture

Please open a new issue and relate it to this one instead of commenting on a year-old, closed, issue.