Điểm:2

Không thể lưu lại các nút bằng thực thể-> lưu (), không có lỗi cụ thể

lá cờ cn

Tôi đang cố gắng viết một lệnh drush để lưu lại tất cả các nút trên trang web của mình.

Tôi đã tìm kiếm một mô-đun và tìm thấy Lưu lại tất cả các nút mô-đun, nhưng lệnh drush của nó chưa sẵn sàng. Vì vậy, tôi quyết định thử tự viết nó.

Tuy nhiên, tôi không thể lưu lại các nút của mình với $entity->save(), và tôi không hiểu tại sao.

<?php

không gian tên Drupal\resave_all_nodes\Commands;

sử dụng Drupal\Core\Entity\EntityTypeManagerInterface;
sử dụng Drupal\node\Entity\Node;
sử dụng Drush\Commands\DrushCommands;

/**
 * Một lớp lệnh Drush để chuyển đổi mô-đun Resave All Nodes.
 */
lớp ResaveAllNodesCommands mở rộng DrushCommands
{

  /**
   * Trình quản lý kiểu thực thể.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  $entityTypeManager riêng tư;


  /**
   * Xây dựng một đối tượng ResaveAllNodesCommands.
   *
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   * Trình quản lý kiểu thực thể.
   */
  chức năng công cộng __construct(EntityTypeManagerInterface $entity_type_manager)
  {
    $this->entityTypeManager = $entity_type_manager;

    cha mẹ::__construct();
  }

  /**
   * Lưu lại tất cả các nút.
   *
   * @command resave-all-nodes:resave
   *
   * @usage drush resave-all-nodes:resave
   * Lưu lại tất cả các nút trên trang web.
   *
   * @aliases chạy
   */
  chức năng công cộng resaveAllNodes()
  {
    $my_node = Nút::load(1);
    $my_node->save();
    \Drupal::logger('resave_all_nodes')->notice("đã lưu nút 1!");
  }
}

Khi tôi chạy lệnh, nhật ký hiển thị các thông báo của trình ghi nhật ký:

  • Tôi thấy "nút 1 đã được lưu!" trong nhật ký
  • Tôi có một thông điệp tường trình khác trong hook_entity_presave(), cũng xuất hiện

Nhưng, khi tôi đi đến /admin/nội dung, "ngày cập nhật" cho nút 1 không thay đổi. Ngoài ra, nội dung của nút không được lưu lại.

nếu tôi đi đến nút/1/chỉnh sửa và lưu lại theo cách thủ công, nút được lưu lại như tôi mong đợi (ngày cập nhật được cập nhật và giá trị trường được cập nhật).

Vì vậy, tại sao nút-> lưu() âm thầm thất bại (ngày cập nhật và giá trị trường vẫn giữ nguyên), khi lưu thủ công hoạt động?

Tôi có một vài mô-đun tùy chỉnh và tôi đã vô hiệu hóa chúng cũng như xây dựng lại bộ đệm, nhưng vấn đề vẫn còn.

lá cờ br
Bạn có bất kỳ logic nào bỏ qua PHP_SAPI hoặc một số mô-đun bỏ qua logic với PHP_SAPI không?
lá cờ cn
@Jonh Tôi không nghĩ vậy. Tôi vừa lấy cơ sở mã của mình cho `PHP_SAPI` và các tham chiếu không phải lõi duy nhất không phải của Symfony là mô-đun biểu mẫu web. Chạy cục bộ trang web của tôi trong lando kéo xuống từ platform.sh.
4uk4 avatar
lá cờ cn
*Nhưng, khi tôi truy cập/admin/content, "ngày cập nhật" cho nút 1 không thay đổi. * Bạn cần đặt thời gian đã thay đổi: `$my_node->setChangedTime(\Drupal::time()->getRequestTime ());` Nếu vẫn không thấy thì thử xóa cache đi.
lá cờ cn
@ 4k4 Ok, cái đó đã hoạt động. Vì vậy, việc lưu lại một nút trong giao diện người dùng thực sự khác với việc thực hiện nút-> lưu(), trong đó nút-> lưu() không thực hiện bất kỳ thay đổi nào trừ khi bạn chỉ định rõ ràng chúng?
lá cờ cn
Các thực thể không lưu giữ dữ liệu nếu không có gì thay đổi (vì lý do rõ ràng về hiệu suất). Việc gửi một biểu mẫu thực thể sẽ cập nhật dấu thời gian đã thay đổi trước khi lưu được gọi, vì vậy tính bền vững được kích hoạt. Bạn chỉ cần làm tương tự
Điểm:2
lá cờ cn

Nhờ có @4k4 và @Clive mà tôi đã có thể làm việc này. Lệnh drush này lưu tất cả các nút. Đoạn mã sau, nhưng trước tiên một số lưu ý:

  • Sau khi gọi lô_set(), đối với các lệnh drush, bạn phải gọi drush_backend_batch_ process() hoặc lô sẽ không bao giờ được chạy.
  • Các Mô-đun ví dụ xử lý hàng loạt Drush 9 là một ví dụ rất hữu ích.
  • trong bạn hàng loạtOperation() lệnh, nếu bạn đánh máy bối cảnh $, bạn phải sử dụng \DrushBatchContext|mảng $context không chỉ là mảng bởi vì drush sẽ sụp đổ mạnh mẽ. Có hàng chục vấn đề trên drupal.org về điều này.

Ok, đây là mã của tôi:

<?php

không gian tên Drupal\resave_all_nodes\Commands;

sử dụng Drupal\Core\Batch\BatchBuilder;
sử dụng Drupal\Core\Entity\EntityTypeManagerInterface;
sử dụng Drupal\Core\StringTranslation\StringTranslationTrait;
sử dụng Drush\Commands\DrushCommands;

/**
 * Một lớp lệnh Drush để chuyển đổi mô-đun Resave All Nodes.
 */
lớp ResaveAllNodesCommands mở rộng DrushCommands
{
  sử dụng StringTranslationTrait;

  /**
   * Trình quản lý kiểu thực thể.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  $entityTypeManager riêng tư;


  /**
   * Xây dựng một đối tượng ResaveAllNodesCommands.
   *
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   * Trình quản lý kiểu thực thể.
   */
  chức năng công khai __construct(EntityTypeManagerInterface $entity_type_manager)
  {
    $this->entityTypeManager = $entity_type_manager;

    cha mẹ::__construct();
  }

  /**
   * Lưu lại tất cả các nút.
   *
   * @command resave:nodes
   *
   * @usage drush resave:nodes
   * Lưu lại tất cả các nút trên trang web.
   *
   * @aliases đã chạy
   */
  chức năng công cộng resaveAllNodes()
  {
    // Một mảng có nhiều ID nút.
    $nids = $this->getNodeIds();
    // Cắt mảng thành các mảng con (khối) có kích thước xác định.
    $chunks = array_chunk($nids, 250);
    $num_chunks = đếm($chunks);

    // Bây giờ lưu lại tất cả các nút theo từng đoạn.
    $batchBuilder = BatchBuilder mới();
    for ($i = 0; $i < $num_chunks; $i++) {
      $batchBuilder->addOperation('\Drupal\resave_all_nodes\Batch\ResaveAllNodesBatch::batchOperation',
        [$chunks[$i]]
      );
    }

    $batchBuilder->setTitle(t('Lưu lại các nút'))
      ->setFinishCallBack('\Drupal\resave_all_nodes\Batch\ResaveAllNodesBatch::batchFinished');

    batch_set($batchBuilder->toArray());
    drush_backend_batch_ process();
  }

  /**
   * Nhận ID nút mảng.
   *
   * @return mảng|int
   * Tốt nhất là một mảng ID nút.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   */
  hàm công khai getNodeIds() {
    $query = $this->entityTypeManager->getStorage('node')->getQuery();
    $nids = $query->execute();
    # Để có được các loại nút.
    # $nids = $query->condition('type', $node_types, 'IN')->execute();

    trả lại $ nids;
  }
}

Đă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.