The existing code
when a form is submitted I execute this batch :
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$node_titles = ['node1', 'node2', 'node3', 'node4', 'node5'];
$batch_builder = (new BatchBuilder())
->setTitle(t('Processing Batch'))
->setInitMessage('Batch is starting')
->setProgressMessage('Processed @current out of @total.')
->setErrorMessage('Batch has encountered an error');
$batch_builder->addOperation(['Drupal\drupolo_batch\Controller\NodeUpdate','run'], $node_titles);
batch_set($batch_builder->toArray());
}
The batch_set()
method always calls a static method, and this works as expected:
public static function run($title, $etm, &$context) {
$node_storage = \Drupal::entityTypeManager()->getStorage('node');
$values = [
'type' => 'article',
'title' => $title,
];
$node = $node_storage->create($values);
$node->save();
$context['results'][] = '';
}
Problem
I want to access the injected service: $this->entityTypeManager
, so I have tried to use a non-static method to access the injected entityTypeManager service.
When I try this:
<?php
namespace Drupal\drupolo_batch\Controller;
use Drupal\Core\Entity\EntityTypeManagerInterface;
class NodeUpdate {
public $entityManager;
public function __construct(EntityTypeManagerInterface $entityManager) {
$this->entityTypeManager = $entityManager;
}
....
public function run($title,$etm, &$context) {
kint($this->entityTypeManager); die();
}
}
I get this error :
ResponseText: Error: Using $this when not in object context in Drupal\drupolo_batch\Controller\ NodeUpdate::run() (line 15 of NodeUpdate.php).
!! the method call is still static ::run()
Solution that doesn't work for me
- I have declared my class as a service with the proper dependencies:
services:
drupolo_batch.node_update:
class: Drupal\drupolo_batch\Controller\NodeUpdate
arguments: ['@entity_type.manager']
- In
addOperation
method I have passed my service
$service = \Drupal::service('drupolo_batch.node_update');
$batch_builder->addOperation([ $service ,'run'], $node_titles);
- This is called in a non-static way but I get this error :
The website encountered an unexpected error. Please try again later.
AssertionError: The container was serialized. in assert() (line 28 of core/lib/Drupal/Core/DependencyInjection/Container.php).
assert(, 'The container was serialized.') (Line: 28)
Drupal\Core\DependencyInjection\Container->__sleep()
serialize(Array) (Line: 89)
Drupal\Core\Queue\DatabaseQueue->doCreateItem(Array) (Line: 56)
Drupal\Core\Queue\DatabaseQueue->createItem(Array) (Line: 993)
_batch_populate_queue(Array, 0) (Line: 899)
batch_process() (Line: 63)
Drupal\Core\Form\FormSubmitter->doSubmitForm(Array, Object) (Line: 593)
Drupal\Core\Form\FormBuilder->processForm('codimth_batch_form', Array, Object) (Line: 321)
Drupal\Core\Form\FormBuilder->buildForm(Object, Object) (Line: 91)
Drupal\Core\Controller\FormController->getContentResult(Object, Object)
call_user_func_array(Array, Array) (Line: 123)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber{closure}() (Line: 573)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 124)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array) (Line: 97)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber{closure}() (Line: 151)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 68)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 57)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 106)
Drupal\page_cache\StackMiddleware\PageCache->pass(Object, 1, 1) (Line: 85)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 38)
Drupal\webprofiler\StackMiddleware\WebprofilerMiddleware->handle(Object, 1, 1) (Line: 52)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 708)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Question
- Is there any way to call the batch method non statically to access
the injected services?
- What is the cause of the previous error and how can I fix it?
- Should I pass the services as parameters instead of injecting them into my service?