カスタムDrushコマンドでコンテンツを生成する
Drushコマンドを用いてコンテンツの作成を行ってみます。
Drushコマンド作成の基本的な方法については、前回の記事「Drushのカスタムコマンドを作成する」をご覧ください。
今回は「drush_create_node」という名前でモジュールを作成します。
作成するファイルは前回と同様、下記の4種類となります。
- drush_create_node.info.yml
- drush.services.yml
- composer.json
- src/Commands/CreateNode.php
次のような構造になります。
では順に作成していきましょう。
① 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();
することでコンテンツが保存されます。
これでモジュールは完成です。ブラウザ上でモジュールを有効化し、実際にコマンドを実行してみましょう。
コマンドの実行
今回はコンテンツタイトルを引数に取っているので、"drush cn [title]"と打つ必要があります。
"drush cn"だけでは"Not enough arguments (missing: "title")."というエラーが出て実行されません。
# drush cn test
実際にコンテンツが作成されているか確認しにいきます。
コード通りに作成されていました。
コンテンツタイプが正しいかどうかチェック
今回はデフォルトで存在する「基本ページ」をコンテンツタイプとして設定しましたが、存在しないコンテンツタイプを指定することもできてしまいます。その場合、整合性のないコンテンツが作成され、そのコンテンツを見ようとするとエラーが発生します。
そこで、指定したコンテンツタイプが実在するかどうか事前にチェックする処理を追加してみます。
まず、"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" が存在しません.
- 閲覧数 343
コメントを追加