Puncte:0

Batch Error: Using $this when not in object context, so Can I call batch method in non static way?

drapel sy

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

  1. 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']
  1. In addOperation method I have passed my service
$service = \Drupal::service('drupolo_batch.node_update');
$batch_builder->addOperation([ $service ,'run'], $node_titles);
  1. 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

  1. Is there any way to call the batch method non statically to access the injected services?
  2. What is the cause of the previous error and how can I fix it?
  3. Should I pass the services as parameters instead of injecting them into my service?
drapel cn
De ce să nu folosiți `\Drupal::service` în metoda statică în sine? În caz contrar, serviciul `drupolo_batch.node_update` trebuie să fie serializabil, astfel încât să poată fi stocat în baza de date cu opțiunea batch.
Jaypan avatar
drapel de
Cred că numărul de eroare pentru #3 este rezultatul faptului că entityTypeManager este public. Încercați să îl schimbați în protejat.
Marwen Amri avatar
drapel sy
@Clive Prefer să injectez serviciile pentru testarea unitară ușoară și, de asemenea, acest serviciu va fi folosit de alte servicii, așa că vă mulțumesc, voi încerca să serializez serviciul,
Jaypan avatar
drapel de
Nu trebuie să serializați singur serviciul, trebuie doar să vă asigurați că este serializabil. După cum am spus în comentariul meu anterior, cred că setarea managerului de tip de entitate ca public poate cauza problema dvs., deoarece cred că provoacă erori de serializare.
Marwen Amri avatar
drapel sy
@Jaypan Am protejat deja prop entityTypeManager, dar asta nu funcționează, încă mai am aceeași eroare, oricum mulțumesc, dar voi folosi metoda satică.
Jaypan avatar
drapel de
În acest caz, sugestia lui Clive de a utiliza un apel static din metoda dvs. statică este modul în care va trebui să procedați.

Postează un răspuns

Majoritatea oamenilor nu înțeleg că a pune multe întrebări deblochează învățarea și îmbunătățește legătura interpersonală. În studiile lui Alison, de exemplu, deși oamenii își puteau aminti cu exactitate câte întrebări au fost puse în conversațiile lor, ei nu au intuit legătura dintre întrebări și apreciere. În patru studii, în care participanții au fost implicați în conversații ei înșiși sau au citit transcrieri ale conversațiilor altora, oamenii au avut tendința să nu realizeze că întrebarea ar influența – sau ar fi influențat – nivelul de prietenie dintre conversatori.