Điểm:0

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

lá cờ 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?
lá cờ cn
Tại sao không sử dụng `\Drupal::service` trong chính phương thức tĩnh? Mặt khác, dịch vụ `drupolo_batch.node_update` cần phải được tạo theo thứ tự để có thể lưu trữ trong cơ sở dữ liệu với op hàng loạt.
Jaypan avatar
lá cờ de
Tôi nghĩ số lỗi #3 là kết quả của việc công khai entityTypeManager. Hãy thử thay đổi nó thành được bảo vệ.
Marwen Amri avatar
lá cờ sy
@Clive Tôi thích đưa các dịch vụ vào để kiểm tra đơn vị dễ dàng và cũng vì dịch vụ này sẽ được các dịch vụ khác sử dụng, vì vậy cảm ơn bạn, tôi sẽ cố gắng tuần tự hóa dịch vụ,
Jaypan avatar
lá cờ de
Bạn không cần phải tự đánh số thứ tự cho dịch vụ, bạn chỉ cần đảm bảo rằng nó có thể đánh số thứ tự được. Như tôi đã nói trong nhận xét trước đây của mình, tôi tin rằng việc đặt trình quản lý loại thực thể là công khai có thể gây ra sự cố của bạn, vì tôi tin rằng nó gây ra lỗi tuần tự hóa.
Marwen Amri avatar
lá cờ sy
@Jaypan Tôi đã bảo vệ chống đỡ thực thểTypeManager nhưng nó không hoạt động, vẫn có lỗi tương tự, dù sao cũng cảm ơn bạn nhưng tôi sẽ chỉ sử dụng phương pháp satic.
Jaypan avatar
lá cờ de
Trong trường hợp đó, đề xuất của Clive về việc sử dụng lệnh gọi tĩnh từ phương thức tĩnh của bạn là cách bạn cần tiếp tục.

Đăng câu trả lời

Hầu hết mọi người không hiểu rằng việc đặt nhiều câu hỏi sẽ mở ra cơ hội học hỏi và cải thiện mối quan hệ giữa các cá nhân. Ví dụ, trong các nghiên cứu của Alison, mặc dù mọi người có thể nhớ chính xác có bao nhiêu câu hỏi đã được đặt ra trong các cuộc trò chuyện của họ, nhưng họ không trực giác nhận ra mối liên hệ giữa câu hỏi và sự yêu thích. Qua bốn nghiên cứu, trong đó những người tham gia tự tham gia vào các cuộc trò chuyện hoặc đọc bản ghi lại các cuộc trò chuyện của người khác, mọi người có xu hướng không nhận ra rằng việc đặt câu hỏi sẽ ảnh hưởng—hoặc đã ảnh hưởng—mức độ thân thiện giữa những người đối thoại.