The SmsGatewayForm doesn't work anymore on Drupal 8.4.0 due to some changes to DefaultSingleLazyPluginCollection in #2851635: DefaultSingleLazyPluginCollection retains stale instance IDs.

The failure is because the new implementation expects non-null plugin IDs to be provided to the DefaultSingleLazyPluginCollection's constructor. This is not what is currently done by the SmsGatewayForm #2857911-12: Use setConfiguration() to merge default configuration values

SmsGateway::getPluginCollections() gets called without any initial values by EntityForm::copyFormValuesToEntity() without the plugin type first being initialized. This is because of how our SmsGatewayForm is implemented: the form is first created without specifying the plugin type because we want to use the same form to choose the plugin type.

Solution - override the DefaultSingleLazyPluginCollection constructor and check for non-null plugin ID first before trying to instantiate it.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

almaudoh created an issue. See original summary.

almaudoh’s picture

Funny that the patch didn't trigger testbot. Re-uploading...

almaudoh’s picture

Title: SmsGatewayForm has been broken by changes to DefaultSingleLazyPluginCollection » SmsGatewayForm has been broken by changes to DefaultSingleLazyPluginCollection in D8.4.x

Status: Needs review » Needs work

The last submitted patch, 2: test.patch, failed testing.

almaudoh’s picture

Status: Needs work » Needs review
FileSize
1.56 KB

Plugin auto-discovery and configuration is still murky waters for me. I've used the simplest approach possible. Hope it doesn't break any tests.

Also fixed a couple of docs nits along the way.

Status: Needs review » Needs work

The last submitted patch, 5: 2857911-5.patch, failed testing.

dpi’s picture

I'm still a little while off setting up a 8.4.x site, so I don't think Ill give this attention for a while.

Could this be the issue? Configurable plugins should merge default configuration values within setConfiguration()

almaudoh’s picture

Could this be the issue? Configurable plugins should merge default configuration values within setConfiguration()

Yep! That was the issue. Funny I'd been following that issue and yet it never occurred to me that it was the cause.

So, here's the final fix.

almaudoh’s picture

Status: Needs work » Needs review
dpi’s picture

@@ -71,7 +71,7 @@ class SmsGateway extends ConfigEntityBase implements SmsGatewayInterface, Entity
    *
    * @var string
    */
-  protected $plugin;
+  protected $plugin = 'log';

???

dpi’s picture

Title: SmsGatewayForm has been broken by changes to DefaultSingleLazyPluginCollection in D8.4.x » Use setConfiguration() to merge default configuration values
Status: Needs review » Needs work
almaudoh’s picture

+ protected $plugin = 'log';
???

That's what makes this patch work actually.

This is the problem: in Entity\SmsGateway

  /**
   * Encapsulates the creation of the SMS gateway SingleLazyPluginCollection.
   *
   * @return \Drupal\sms\Plugin\SmsGatewayPluginCollection
   *   The SMS gateway plugin collection.
   */
  protected function getPluginCollection() {
    if (!$this->pluginCollection) {
      $this->pluginCollection = new SmsGatewayPluginCollection(
        \Drupal::service('plugin.manager.sms_gateway'),
        $this->plugin,
        $this->settings
      );
    }
    return $this->pluginCollection;
  }

  /**
   * {@inheritdoc}
   */
  public function getPluginCollections() {
    return ['settings' => $this->getPluginCollection()];
  }

SmsGateway::getPluginCollections() gets called without any initial values by EntityForm::copyFormValuesToEntity() without the plugin type first being initialized. This is because of how our SmsGatewayForm is implemented: the form is first created without specifying the plugin type because we want to use the same form to choose the plugin type.

dpi’s picture

This is weird. There are different problems if we are required to hard code a fallback plugin id.

almaudoh’s picture

I just encountered this issue again (I'd forgotten about it). Drupal 8.4.0-beta1 is out, stable is due in October. We need to fix this.

There are different problems if we are required to hard code a fallback plugin id

What kind of problems are you seeing?

The only other options I can see are to override the DefaultSinglePluginCollection constructor in our SmsGatewayPluginCollection and revert to the original implementation (don't call $this->addInstanceId()), or we change the way we're implementing the plugin form.

I'll post alternative patches later on today.

almaudoh’s picture

So, a much neater approach following #14. No need to hardcode the fallback gateway, but we have to override the constructor and only call $this->addInstanceId() if there is a plugin ID specified.

almaudoh’s picture

Status: Needs work » Needs review

:)

almaudoh’s picture

Issue summary: View changes
Status: Needs review » Reviewed & tested by the community

Tests pass on D8.4. I will commit this by the end of the day if there is no further objection to the approach.

almaudoh’s picture

Issue summary: View changes
dpi’s picture

almaudoh’s picture

Status: Reviewed & tested by the community » Fixed

Ok. Great. Committed / pushed to 8.x-1.x

  • almaudoh committed cefce06 on 8.x-1.x
    Issue #2857911 by almaudoh: Use setConfiguration() to merge default...

Status: Fixed » Closed (fixed)

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