Problem/Motivation
In the WebformHandlerBase class and all subclasses, the initialization of the instance properties is happening.
The purpose of ContainerInjectionInterface::create() (or similar methods like ContainerFactoryPluginInterface::create()) is passing the injected dependencies to the class constructor, non initializing the instance properties.
Steps to reproduce
See: WebformHandlerBase, EmailWebformHandler, Example Handler
Proposed resolution
Rewrite all affected places.
First, replace:
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
$instance = new static($configuration, $plugin_id, $plugin_definition);
$instance->loggerFactory = $container->get('logger.factory');
$instance->configFactory = $container->get('config.factory');
$instance->renderer = $container->get('renderer');
$instance->entityTypeManager = $container->get('entity_type.manager');
$instance->conditionsValidator = $container->get('webform_submission.conditions_validator');
$instance->tokenManager = $container->get('webform.token_manager');
$instance->setConfiguration($configuration);
return $instance;
}
with
public function __construct(array $configuration, $plugin_id, $plugin_definition,
LoggerChannelFactoryInterface $logger_factory, ConfigFactoryInterface $config,
RendererInterface $renderer, EntityTypeManagerInterface $entity_type_manager,
WebformSubmissionConditionsValidator $webform_submission_conditions_validator,
WebformTokenManagerInterface $webform_token_manager) {
$this->configFactory = $config;
parent::__construct($configuration + $this->getConfiguration(), $plugin_id, $plugin_definition);
$this->loggerFactory = $logger_factory;
$this->renderer = $renderer;
$this->entityTypeManager = $entity_type_manager;
$this->conditionsValidator = $webform_submission_conditions_validator;
$this->tokenManager = $webform_token_manager);
}
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('logger.factory'),
$container->get('config.factory'),
$container->get('renderer'),
$container->get('entity_type.manager'),
$container->get('webform_submission.conditions_validator'),
$container->get('webform.token_manager')
);
}
For example for EmailWebformHandler replace this
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
$instance = parent::create($container, $configuration, $plugin_id, $plugin_definition);
$instance->currentUser = $container->get('current_user');
$instance->moduleHandler = $container->get('module_handler');
$instance->languageManager = $container->get('language_manager');
$instance->mailManager = $container->get('plugin.manager.mail');
$instance->themeManager = $container->get('webform.theme_manager');
$instance->tokenManager = $container->get('webform.token_manager');
$instance->elementManager = $container->get('plugin.manager.webform.element');
return $instance;
}
with
public function __construct(array $configuration, $plugin_id, $plugin_definition,
....arguments here....) {
// construct body here.
}
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('current_user'),
$container->get('module_handler'),
$container->get('language_manager'),
$container->get('plugin.manager.mail'),
$container->get('webform.theme_manager'),
$container->get('webform.token_manager'),
$container->get('plugin.manager.webform.element')
);
}
Remaining tasks
- Do refactoring and create patch
And thanks to @apaderno for pointing to this issue. See here: https://www.drupal.org/project/projectapplications/issues/3261372#commen...
Comments
Comment #2
le72Comment #3
juancec commentedHi, I worked on WebformHandlerBase, EmailWebformHandler and ExampleWebformHandler files in 6.x-dev.
I'm providing a patch, please review it. I hope this patch works =)
Comment #4
jrockowitz commentedThis "unconventional" but documented approach to dependency injection allows handlers to be extended while allowing the parent class to add dependencies without breaking anything.
@see https://www.jrockowitz.com/blog/webform-road-to-drupal-9