Score:0

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

ธง 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?
cn flag
ทำไมไม่ใช้ `\Drupal::service` ในเมธอดแบบสแตติกล่ะ มิฉะนั้น บริการ `drupolo_batch.node_update` จะต้องทำให้เป็นอนุกรมเพื่อให้สามารถจัดเก็บไว้ในฐานข้อมูลด้วยชุดการทำงาน
Jaypan avatar
de flag
ฉันคิดว่าหมายเลขข้อผิดพลาดสำหรับ #3 เป็นผลมาจากการให้ entityTypeManager เป็นสาธารณะ ลองเปลี่ยนเป็นป้องกัน
Marwen Amri avatar
sy flag
@Clive ฉันชอบฉีดบริการสำหรับการทดสอบหน่วยอย่างง่าย และเนื่องจากบริการนี้จะถูกใช้บริการอื่น ดังนั้นขอบคุณ ฉันจะพยายามทำให้เป็นอนุกรมบริการ
Jaypan avatar
de flag
คุณไม่จำเป็นต้องซีเรียลไลซ์บริการด้วยตัวคุณเอง คุณเพียงแค่ต้องแน่ใจว่าบริการนั้นซีเรียลไลซ์ได้ ดังที่ฉันได้กล่าวไว้ในความคิดเห็นก่อนหน้านี้ ฉันเชื่อว่าการตั้งค่าผู้จัดการประเภทเอนทิตีเป็นสาธารณะอาจทำให้เกิดปัญหาได้ เนื่องจากฉันเชื่อว่าการตั้งค่านี้ทำให้เกิดข้อผิดพลาดในการออกหมายเลขกำกับ
Marwen Amri avatar
sy flag
@Jaypan ฉันได้ทำให้เอนทิตี TypeManager prop ได้รับการป้องกันแล้ว แต่ไม่ได้ผล แต่ก็ยังมีข้อผิดพลาดเดียวกัน ขอบคุณ แต่ฉันจะใช้วิธี satic
Jaypan avatar
de flag
ในกรณีนั้น คำแนะนำของ Clive ในการใช้การโทรแบบคงที่จากวิธีการแบบคงที่คือวิธีที่คุณจะต้องดำเนินการต่อไป

โพสต์คำตอบ

คนส่วนใหญ่ไม่เข้าใจว่าการถามคำถามมากมายจะปลดล็อกการเรียนรู้และปรับปรุงความสัมพันธ์ระหว่างบุคคล ตัวอย่างเช่น ในการศึกษาของ Alison แม้ว่าผู้คนจะจำได้อย่างแม่นยำว่ามีคำถามกี่ข้อที่ถูกถามในการสนทนา แต่พวกเขาไม่เข้าใจความเชื่อมโยงระหว่างคำถามและความชอบ จากการศึกษาทั้ง 4 เรื่องที่ผู้เข้าร่วมมีส่วนร่วมในการสนทนาด้วยตนเองหรืออ่านบันทึกการสนทนาของผู้อื่น ผู้คนมักไม่ตระหนักว่าการถามคำถามจะมีอิทธิพลหรือมีอิทธิพลต่อระดับมิตรภาพระหว่างผู้สนทนา