Japanese plugin dev 3 4
MTのプラグインを開発するには、MTオブジェクトの利用が必須です。
ここではMTオブジェクトの利用方法を解説します。
MTオブジェクトとはMT::Objectクラスと、それから派生されたMT::BlogやMT::Entryといったクラスの事を指します。派生されたクラスはMT::Objectクラスに独自の実装を加え、それぞれオブジェクト指向のクラスとして動作します。
MTを拡張するには、このMTオブジェクトを操作し各クラスのインスタンスの新規作成や保存、修正、削除などを行います。MTオブジェクトの変更はデータベースと直結しており、SQL文を書く事無くこれらの操作が行えます。具体的にはData Object Driverがオブジェクトの操作とデータベースの操作の中継を行っています。
従来の記述法はMTのクラス名を直接記載する物( MT::Foo
)でしたが、新しい記述方法( MT->model($class_name)
)を使う場面が増えていますので、ここでまとめます。また、今後の解説は新しい記述方法を使います。
MTクラス名を直に記述し、それに対して操作を行います。
my $obj = MT::Foo->new();
クラス名を指定して MT->model($class_name)
でクラス $class
を取得し、それに対して操作を行います。
このようにする事で、例えばコメントクラスとトラックバッククラスに同様の処理を行う際 $class_name
の変更だけで、1コードで処理できる場合があり、コードのメンテナンスが容易になります。
my $class_name = 'foo'; my $class = MT->model($class_name); my $obj = $class->new();
サブタイプを持ったMT::Assetのようなクラスの場合、 MT->models('asset')
とすることで、どのようなサブタイプが含まれるかがわかります。(’asset’, ‘asset.image’, ‘asset.video’, etc.)
my @types = MT->models('asset');
オブジェクトの新規作成は以下のようにクラスに対して new()
を呼ぶ事で実行できます。
my $class = MT->model($class_name); my $obj = $class->new();
また、 $class
を明示的に取得せず、1ラインで以下のように記述することもできます。
my $obj = MT->model($class_name)->new();
取得したいと考えているオブジェクトのidを指定して、オブジェクトを取得します。ここで帰って来るのはオブジェクト $obj
になります。
my $obj = $class->load($id);
上記の load($id)
ではなく、 load( $terms, $args )
と記述する事で、一致条件 $terms
、出力条件 $arg
に合った形でオブジェクトを取得できます。ここで帰って来るのはオブジェクトの配列 @obj
になります。
my $terms = { author_id => $author->id, blog_id => $blog->id }; my $args = { sort => 'created_on', direction => 'ascend', limit => 20 }; my @obj = $class->load( $terms, $args ); for my $obj (@obj) { # do something }
前述の一致条件 $terms
と出力条件 $args
を用いて load_iter( $terms, $args )
を利用すると、イテレータ(データベースのポインタのようなもの)が取得できます。
上述の load()
での全件取得では、取得した分のオブジェクトのメモリが必要となりますが、イテレータの場合はそういった余分なメモリを必要としません。
順繰りにイテレータからオブジェクトを取得するには $obj = $iter->()
とします。
my $iter = $class->load_iter( $terms, $args ); while (my $obj = $iter->()) { # do something }
カラム名をキーとし、そのカラムの内容を値とするハッシュへのリファレンスです。たとえば、fooというカラムの内容が"bar"と一致するようなMT::Fooオブジェクトを読み込むには、loadを次のように呼び出します。
my @foo = MT::Foo->load({ foo => 'bar' });
$args
は出力条件を格納したハッシュへのリファレンスでなければなりません。このハッシュには、以下のパラメーターが指定可能です。
- sort => “column”
- 見つかったオブジェクトを、"column"という名前のカラムの内容でソートします。"column"はインデックスつきのカラムでなければなりません。
- direction => “ascend|descend”
- ソート順の指定で、sortと組み合わせて使います。"ascend"(昇順)か"descend"(降順)のいずれかが指定できます。デフォルトは"ascend"です。
- limit => “N”
- limitの指定がない場合には、デフォルトで条件に合うオブジェクトをすべて読み込みますが、limitを指定すると、オブジェクトの個数の上限をN個にして読み込みます。
- offset => “M”
- limitと組み合わせて使い、最初のN個を返す(offsetの指定がない場合のデフォルト)かわりに、M番目からN個分のオブジェクトを返します。
- start_val => “value”
- limitとsortの両パラメーターと組み合わせて使います。条件に合う最初のN個のオブジェクトを返す代わりに、"column"(ソート基準となるカラム)の値が"value"より大きい最初のN個分のオブジェクトを返します。
- range
- 引数
$terms
の中で、あるカラム名に対する値として配列リファレンスを指定した場合に、これと組み合わせて使います。指定したカラムの値が、ある値に合致するオブジェクトを検索する代わりに、値が指定した範囲内にあるオブジェクトを返すように指示します。 - rangeの値には、ハッシュ・リファレンスを指定します。このハッシュのキーは、範囲として解釈すべきカラムのカラム名で、値はすべて1です。
- 引数
my $class = MT->model('entry'); my @entries = $class->load( { created_on => ['201103010000', '201104010000'] }, { range => { created_on => 1 } } );
- join
- 別のオブジェクトの集合を検索基準あるいはソート基準として、オブジェクトの集合を選択するのに使います。たとえば、最近コメントのついたN個のエントリーを選択する場合などです。この場合、検索基準はMT::Commentオブジェクトですが、返されるオブジェクトはMT::Entryオブジェクトです。このような場合にjoinを使うと、最近のMT::Commentオブジェクトを読み込んでから、それぞれのコメント先であるMT::Entryオブジェクトを個別に読み込むより、処理速度が高速になります。
- このjoinは、SQL文のJOIN演算子とは異なり、返されるオブジェクトが常に1つの型のオブジェクトだけであることに注意してください。上の例では、返されるオブジェクトはMT::Entryオブジェクトだけです。MT::Commentオブジェクトのカラムを含めることはできません。
- joinの一般的な指定方法は以下のとおりです。
join => [ CLASS, JOIN_COLUMN, $terms, $args ]
-
CLASS
は結合に使うクラスです。JOIN_COLUMN
は2つのオブジェクトのテーブルを結合するカラム名です。$terms
と$args
の指定方法は、外側のload
またはload_iter
メソッドの引数と同様で、結合に利用するオブジェクトの選択方法を指定します。 - たとえば、次のようにloadメソッドを使うと、最近コメントがついた10件のエントリーを選択することができます。このコードでは、 unique を指定することにより、返されるMT::Entryオブジェクトに重複がないことが保証されています。このフラグの指定をしない場合、同一のエントリーに2つのコメントがついていると、同じMT::Entryが2つ返されることになります。
my $class = MT->model('entry'); my @entries = $class->load(undef, { 'join' => [ 'MT::Comment', 'entry_id', { blog_id => $blog_id }, { 'sort' => 'created_on', direction => 'descend', unique => 1, limit => 10 } ] });
- unique
- 返されるオブジェクトが一意であることを保証します。
- この指定が意味を持つのは、joinを使うときだけです。というのは、単一のオブジェクトのデータベースからデータを読み込む場合には、返されるオブジェクトは常に一意だからです。
オブジェクトの値を設定するのは簡単です。オブジェクトの bar
要素に文字列 foobar
を設定する場合、以下の様に記述します。
$obj->bar('foobar');
値の取得も設定と同じく簡単です。オブジェクトの bar
要素を以下の様に取得します。上記のように文字列を設定していた場合、 $value
には foobar
が設定されます。
my $value = $obj->bar();
オブジェクトを新規作成したり、値を設定した後、保存をしないと結果がデータベースに格納されません。以下の様に保存 save()
します。
保存出来なかった場合( $obj->save()
が失敗した場合)は異常系のエラーなので、エラーメッセージを出して die
します。
$obj->save() or die $obj->errstr;
オブジェクトをデータベースから削除するには以下の様に remove()
を呼びます。
削除出来なかった場合( $obj->remove()
が失敗した場合)は異常系のエラーなので、エラーメッセージを出して die
します。
$obj->remove() or die $obj->errstr;
オブジェクトをデータベースから一括削除するには以下の様に remove_all()
を呼びます。
削除出来なかった場合( $obj->remove_all()
が失敗した場合)は異常系のエラーなので、エラーメッセージを出して die
します。
$class->remove_all() or die $class->errstr;
オブジェクトをデータベースから子オブジェクトと一緒に削除するには remove
を上書きをし、以下の様に remove_children()
を呼びます。
その上で SUPER::remove
を呼ぶ事で親オブジェクトが削除されます。
sub remove { my $obj = shift; $obj->remove_children({ key => 'class_id' }); $obj->SUPER::remove; }
データベース内にいくつのデータが保存されているかを確認します。 $count
にはデータ数が返ります。
$count = $class->count( $terms, $args );
データベース内にデータが保存されているかを確認します。存在する場合は1を、存在しない場合は0を返します。
if ($foo->exists()) { printf "Foo $foo already exists!"; }
あるオブジェクト $obj
が MT::Foo
のインスタンスかどうかを確認するには isa()
を利用します。
if ( $obj->isa('MT::Foo') ) { # do something }
各クラスの具体的な操作方法は、以下のドキュメントを参考にしてください。
Movable Type オブジェクト・リファレンス(日本語)
Movable Type Perl Documentation(英語)
PHPでMTオブジェクトを利用するのはダイナミックパブリッシングの際のWebページの作成になりますので、MTオブジェクトの利用は読み込みがメインとなります。
MT::Fooオブジェクトを読み込むには以下のように記述します。このようにPHP版のオブジェクト読み込みには専用の関数が用意されており、その関数を利用してオブジェクトを読み込むようになっています。
また、Perl版では公開しているかステータスを明示する必要がありましたが、PHP版では公開しているオブジェクトしか取得できません。
$mt = $ctx->mt; $obj = $mt->db()->fetch_foo($foo_id);
$args['class'] = 'foo'; $args['blog_id'] = $blog_id; $args['offset'] = 20; $args['limit'] = 10; $mt = $ctx->mt; $obj = $mt->db()->fetch_foos($args);
以下、主な関数です。
クラス | 関数 |
MT::Website | fetch_website( $website_id ) |
MT::Website(複数) | fetch_websites( $args ) |
MT::Blog | fetch_blog( $blog_id ) |
MT::Blog(複数) | fetch_blogs( $args ) |
MT::Template(複数) | fetch_templates( $args ) |
MT::Page | fetch_page( $page_id ) |
MT::Page(複数) | fetch_pages( $args ) |
MT::Entry | fetch_entry( $entry_id ) |
MT::Entry(複数) | fetch_entries( $args, &$total_count ) |
MT::Category | fetch_category( $cat_id ) |
MT::Category(複数) | fetch_categories( $args ) |
MT::Folder | fetch_folder( $folder_id ) |
MT::Folder(複数) | fetch_folders( $args ) |
MT::Author | fetch_author( $author_id ) |
MT::Author(複数) | fetch_authors( $args ) |
MT::Comment | fetch_comment( $comment_id ) |
MT::Comment(複数) | fetch_comments( $args ) |
今回の解説で、MTのプログラミングではSQL文を書かずにオブジェクトがデータベースに出し入れされる事と、オブジェクトの利用が平易である事がわかっていただけたと思います。
この解説や Movable Type オブジェクト・リファレンス(日本語) 、 Movable Type Perl Documentation(英語) を参考にプラグイン開発を楽しんで下さい。
- プラグイン開発のためのファーストステップ
- レジストリ、YAMLについて
- 環境変数について
- プラグインのローカライゼーションについて
- テストドリブンでのプラグインの開発について
- グローバル・モディファイアプラグインの開発について
- ファンクションタグ プラグインの開発について
- ブロックタグ プラグインの開発について
- コンディショナルタグ プラグインの開発について
- プラグインのデバッグ
- プラグインの設定方法
- コールバックとフックポイント
- スケジュールタスクの開発
- MTオブジェクトの利用方法
- 独自オブジェクトの作成
- 新規アプリケーションの作成
- Transformerプラグインの開発
- 管理画面のメニュー修正
- リストアクションの追加
- 動作モードの追加とモーダルウィンドウの表示
- 外部Web APIとの連携
- 権限とロール