web-dev-qa-db-ja.com

コンテンツが非公開のときにカスタムモジュールで関数をトリガーするにはどうすればよいですか?

要するに:

Drupal 8を使用して、特定のコンテンツタイプのエンティティ更新イベントに「フック」して、そのイベントが発生したときにさらにアクションを実行できるようにしたいと考えています。この場合、削除非公開の場合はノード。

長い間:

Scheduler モジュールを使用すると、ノードのスケジュールを設定して、スケジュールどおりに公開および非公開にすることができます。私の目標は、特定のタイプのノードが非公開になったときに削除することです。

最初に Rules モジュールを使用して、非公開ノードの削除をトリガーしようとしました。ただし、現在、私のWebサイトでルールが適切に機能していません(非公開イベントノードタイプを構成しようとするとエラーが発生します)。小さなカスタムモジュールを使用して同じタスクを実行する方法に興味をそそられます。 Drupal 8モジュールとモジュール開発をよりよく理解することを目標に前進しています。

その結果、コンテンツタイプの非公開イベントの処理をモジュールコードに移動したいと考えています。私が見つけている他の例は、Drupal 7に関連しています。Drupal 8モジュールを構築しています。

これが、これまでの私の開始モジュールコードです(ラフ、ドラフト、未テスト

モジュール構造:

hour_helper
  hour_helper.info.yml
  hour_helper.services.yml
  src
    EventSubscriber
      HourUnpublishEventSubscriber.php

hour_helper.info.yml:

name: Hours of Operation Helper
type: module
description: 'Utilities to assist with hours of operation, starting with the removal of hour content once it is unpublished via the scheduler module.'
package: Custom
core: 8.x

hour_helper.services.yml:

services:
  hour_helper.node_subscriber:
    class: Drupal\hour_helper\EventSubscriber
    arguments: ['@entity.manager']
    tags:
      - { name: event_subscriber }

HourUnpublishEventSubscriber.php:

<?php

/**
 * @file
 * Event subscriber
 */

namespace Drupal\hour_helper\EventSubscriber;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;

//!!! use (... something entity or node related, we want to subscribe to entity updates?)

/**
 * Remove hour of opperation nodes after/when they are scheduled to unsubscribe to prevent garbage accumulation
 */
class HourUnpublishSubscriber implements EventSubscriberInterface  {
  /**
   * {@inheritdoc}
   */
  public function getSubscribedEvents() {

    // Subscribe to node update events with priority 0.
    //!!! which event....
    $events[SomethingEvents::SOMETHING][] = array('checkForRemoveStatus');
    return $events;
  }

  /**
   * This method is called whenever the ????? event is dispatched.
   *
   * @param GetResponseEvent $event
   */
  public function checkForRemoveStatus(GetResponseEvent $event) {

    //print '<pre>';
    //print_r($event);
    //print '</pre>';


    die('Well, at least an event has been triggered to be handled here...');

  }

}

私は熟考し続けます Drupalイベントドキュメントページ ...

2

これに基づいて:私の目標は、非公開になったときに特定のタイプのノードを削除することです

hook_ENTITY_TYPE_update を使用できます。

(元の)エンティティが公開されておらず、そのタイプが探しているエンティティであるかどうかを確認する必要があります。

+1:OOの観点から、 events を確認することもできます。

1
ssibal

これは、Drupal 8のルール)で非常に簡単に実行できます。これは、最初に要求したものです...以下のルールを記述してテストするのに1分もかかりませんでした。

ルールは、実際にはすべてのエンティティCRUD操作(カスタムタイプを含むすべてのタイプのすべてのエンティティ)のイベントを自動的に生成し、条件付きでアクションを実行するためにそれらのイベントに反応できます。これらのイベントを使用可能にするためだけにルールを有効にして、カスタムコードでそれらに対応できるようにする場合は、それを実行できます。ただし、ルールを使用すると、最初と将来の両方でタスクの詳細を変更したい場合に、操作を簡単にプロトタイプ化および変更できるため、タスク全体にルールを使用する方がはるかに便利です。ビューを使用すると、実装の詳細をあまり知らなくても、複雑なDBクエリの結果を簡単に作成および表示できるように、ルールを使用してワークフローを追加およびカスタマイズできます。

ここに、あなたが要求したことを達成する完全な例があります。 Drupalで事前にインストールされているので、以下のルールがどのサイトでも機能するように、コンテンツタイプ「基本ページ」を使用することを選択しました。特定のタイプ(またはタイプ、この例では、更新によってページのステータスが公開から非公開に変更された場合にのみ、更新された基本ページが削除されます。また、発生したことをユーザーに通知するメッセージも表示されます。

前述のとおり、必要に応じて、これを変更したり、条件を追加したり、アクションを追加したり、ルールをトリガーするタイプを変更したりできます。

langcode: en
status: true
dependencies: {  }
id: delete_content_of_type_basic_page_when_it_it_unpublished
label: 'Delete content of type "Basic page" when it it unpublished'
events:
  -
    event_name: 'rules_entity_update:node--page'
description: 'For https://drupal.stackexchange.com/questions/203680/how-do-i-make-a-custom-module-trigger-a-function-when-content-is-unpublished?rq=1'
tags: {  }
weight: 0
config_version: '3'
expression:
  id: rules_rule
  uuid: 4d5f5940-5d74-4402-9391-b2d0261f0194
  weight: 0
  conditions:
    id: rules_and
    uuid: 5c39832c-eed4-4ec7-b5c7-36f29879e22b
    weight: 0
    conditions:
      -
        id: rules_condition
        uuid: 7152f83f-5481-41bf-8f20-c8f3f0d89c48
        weight: 0
        context_values: {  }
        context_mapping:
          node: node_unchanged
        context_processors: {  }
        provides_mapping: {  }
        condition_id: rules_node_is_published
        negate: false
      -
        id: rules_condition
        uuid: 1694c6b6-96f7-4eb6-9026-3e7140bb2be9
        weight: 0
        context_values: {  }
        context_mapping:
          node: node
        context_processors: {  }
        provides_mapping: {  }
        condition_id: rules_node_is_published
        negate: true
  actions:
    id: rules_action_set
    uuid: d9e46518-c5e6-4839-8de8-3175b184a6fd
    weight: 0
    actions:
      -
        id: rules_action
        uuid: 8afb621c-3518-44bd-8a31-e1c2f7b0bc5b
        weight: 0
        context_values: {  }
        context_mapping:
          entity: node
        context_processors: {  }
        provides_mapping: {  }
        action_id: rules_entity_delete
      -
        id: rules_action
        uuid: 1f554fa6-2a44-4d03-985d-f87412cd0843
        weight: 0
        context_values:
          message: 'The basic page "{{ node.title }}" was deleted'
          type: status
          repeat: true
        context_mapping: {  }
        context_processors:
          message:
            rules_tokens: {  }
          type:
            rules_tokens: {  }
          repeat:
            rules_tokens: {  }
        provides_mapping: {  }
        action_id: rules_system_message
0
anonymous

独自のContentEntityの場合は、ContentEntityFormの子孫の::save()メソッドをフックします(ここで\Drupal::service('event_dispatcher')->dispatch(... something ...)を使用することもできます。これはOOになります。

これを行うことができない場合は、 hook_entity_update を使用してください。これはOOではありません。しかし、現在のところ、コアにはEventはありません。

よろしく、

ライナー

0
Rainer Feike