カスタムDrushコマンドでコンテンツを生成する

  •  
 
funada2020年7月29日 - 15:02 に投稿

タグ

カスタムDrushコマンドでコンテンツを生成する

Drushコマンドを用いてコンテンツの作成を行ってみます。
Drushコマンド作成の基本的な方法については、前回の記事「Drushのカスタムコマンドを作成する」をご覧ください。

今回は「drush_create_node」という名前でモジュールを作成します。
作成するファイルは前回と同様、下記の4種類となります。

  • drush_create_node.info.yml
  • drush.services.yml
  • composer.json
  • src/Commands/CreateNode.php

次のような構造になります。

files

では順に作成していきましょう。

① drush_create_node.info.yml

name: Drush Create Node
description: 'コンテンツを作成します.'
core: 8.x
type: module

② drush.services.yml

services:
  drush_create_node.commands:
    class: \Drupal\drush_create_node\Commands\CreateNode
    tags:
      - { name: drush.command }

③ composer.json

{
  "name": "drupal/drush_create_node",
  "type": "drupal-module",
  "autoload": {
    "psr-4": {
      "Drupal\\drush_create_node\\": "src/"
    }
  },
  "extra": {
    "drush": {
      "services": {
        "drush.services.yml": "^9"
      }
    }
  }
}

ここまでは前回と同じです。

④ CreateNode.php

<?php

namespace Drupal\drush_create_node\Commands;

use Drush\Commands\DrushCommands;
use Drupal\node\Entity\Node;

class CreateNode extends DrushCommands {

  /**
   * @command create-node
   * @aliases cn
   */
  public function createNode($title) {
    $node = Node::create([
      'title' => $title,
      'type' => 'page',
      'body' => 'Drushコマンドによって生成されたコンテンツです。',
      'uid' => 1,
    ]);
    $node->save();
  }

}

コンテンツを作成するためには、Nodeクラスを使う必要があります。
始めに use Drupal\node\Entity\Node; の1行を入れておきましょう

@command create-node の部分はコマンドとなる文字列を定義しています。
1行下の @aliases cn という部分はコマンドの短縮形です。"drush create-node"と打っても"drush cn"と打っても同じ結果が得られます。ただし、このように2文字の短縮形は既存のコマンドと被ってしまうおそれがあるので注意しましょう。

続いて関数 createNode() の中身についてです。
Node::create() は"title", "type"などを含む連想配列を引数に取り、オブジェクトを返します。"title"はコンテンツのタイトル、"type"はコンテンツタイプの内部名称です。この2つは必須になります。("page"は「基本ページ」のことです。)
"uid"はコンテンツの作成者です。"1"とするとrootユーザーが作成したことになり、指定しなければ匿名ユーザーになります。

create() によって渡されたオブジェクトを $node->save(); することでコンテンツが保存されます。

これでモジュールは完成です。ブラウザ上でモジュールを有効化し、実際にコマンドを実行してみましょう。

コマンドの実行

install

今回はコンテンツタイトルを引数に取っているので、"drush cn [title]"と打つ必要があります。
"drush cn"だけでは"Not enough arguments (missing: "title")."というエラーが出て実行されません。

# drush cn test

実際にコンテンツが作成されているか確認しにいきます。

content

コード通りに作成されていました。

コンテンツタイプが正しいかどうかチェック

今回はデフォルトで存在する「基本ページ」をコンテンツタイプとして設定しましたが、存在しないコンテンツタイプを指定することもできてしまいます。その場合、整合性のないコンテンツが作成され、そのコンテンツを見ようとするとエラーが発生します。

そこで、指定したコンテンツタイプが実在するかどうか事前にチェックする処理を追加してみます。

まず、"Drupal\node\Entity\NodeType"を追加でuseします。

<?php
 
namespace Drupal\faines_test\Commands;
 
use Drush\Commands\DrushCommands;
use Drupal\node\Entity\Node;
use Drupal\node\Entity\NodeType; //追加

次に、 $node->save(); の直前に下記のコードを追加します。

    // サイトに存在するコンテンツタイプの一覧を取得.
    $node_types = NodeType::loadMultiple();
    $node_type_names = [];
    foreach ($node_types as $node_type) {
      $node_type_names[] = $node_type->id();
    }

    // 指定されたコンテンツタイプが存在しなければ作成を中止.
    if (!in_array($node->getType(), $node_type_names)) {
      $this->output()->writeln('コンテンツタイプ "' . $node->getType() . '" が存在しません.');
      return;
    }

これで完了です。
Node::create() の中の"page"を"hoge"に変えてみましょう。

    $node = Node::create([
      'title' => $title,
      'type' => 'hoge',
      'body' => 'Drushコマンドによって生成されたコンテンツです。',
      'uid' => 1,
    ]);

これで実行してみると、コンテンツは作成されずにメッセージが表示されます。

# drush cn test
コンテンツタイプ "hoge" が存在しません.

コメントを追加

プレーンテキスト

  • HTMLタグは利用できません。
  • 行と段落は自動的に折り返されます。
  • ウェブページのアドレスとメールアドレスは自動的にリンクに変換されます。
CAPTCHA
この質問はあなたが人間の訪問者であるかどうかをテストし、自動化されたスパム送信を防ぐためのものです。