Skip to content

Japanese plugin dev 3 4

uehatsu edited this page May 10, 2011 · 29 revisions

MTオブジェクトの利用方法

はじめに

MTのプラグインを開発するには、MTオブジェクトの利用が必須です。

ここではMTオブジェクトの利用方法を解説します。

MTオブジェクトとは?

MTオブジェクトとはMT::Objectクラスと、それから派生されたMT::BlogやMT::Entryといったクラスの事を指します。派生されたクラスはMT::Objectクラスに独自の実装を加え、それぞれオブジェクト指向のクラスとして動作します。

MTを拡張するには、このMTオブジェクトを操作し各クラスのインスタンスの新規作成や保存、修正、削除などを行います。MTオブジェクトの変更はデータベースと直結しており、SQL文を書く事無くこれらの操作が行えます。具体的にはData Object Driverがオブジェクトの操作とデータベースの操作の中継を行っています。

MTオブジェクトの利用方法(perl)

従来の記述法とこれからの記述法

従来の記述法は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指定してのload)

取得したいと考えているオブジェクトのidを指定して、オブジェクトを取得します。ここで帰って来るのはオブジェクト $obj になります。

my $obj = $class->load($id);

オブジェクトをすべて読み込む($terms, $argsを指定してのload)

上記の 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
}

オブジェクトを一つずつ読み込む(load_iter)

前述の一致条件 $terms と出力条件 $args を用いて load_iter( $terms, $args ) を利用すると、イテレータ(データベースのポインタのようなもの)が取得できます。

上述の load() での全件取得では、取得した分のオブジェクトのメモリが必要となりますが、イテレータの場合はそういった余分なメモリを必要としません。

順繰りにイテレータからオブジェクトを取得するには $obj = $iter->() とします。

my $iter = $class->load_iter( $terms, $args );
while (my $obj = $iter->()) {
    # do something
}

$termsと$argsとは?

$termsについて

カラム名をキーとし、そのカラムの内容を値とするハッシュへのリファレンスです。たとえば、fooというカラムの内容が"bar"と一致するようなMT::Fooオブジェクトを読み込むには、loadを次のように呼び出します。

my @foo = MT::Foo->load({ foo => 'bar' });

$argsについて

$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!";
}

オブジェクトの確認方法

あるオブジェクト $objMT::Foo のインスタンスかどうかを確認するには isa() を利用します。

if ( $obj->isa('MT::Foo') ) {
    # do something
}

その他のMTオブジェクトの操作方法

各クラスの具体的な操作方法は、以下のドキュメントを参考にしてください。

Movable Type オブジェクト・リファレンス(日本語)
Movable Type Perl Documentation(英語)

MTオブジェクトの利用方法(PHP)

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(英語) を参考にプラグイン開発を楽しんで下さい。

プラグイン開発ガイド インデックス

  1. プラグイン開発のためのファーストステップ
  2. レジストリ、YAMLについて
  3. 環境変数について
  4. プラグインのローカライゼーションについて
  5. テストドリブンでのプラグインの開発について
  6. グローバル・モディファイアプラグインの開発について
  7. ファンクションタグ プラグインの開発について
  8. ブロックタグ プラグインの開発について
  9. コンディショナルタグ プラグインの開発について
  10. プラグインのデバッグ
  11. プラグインの設定方法
  12. コールバックとフックポイント
  13. スケジュールタスクの開発
  14. MTオブジェクトの利用方法
  15. 独自オブジェクトの作成
  16. 新規アプリケーションの作成
  17. Transformerプラグインの開発
  18. 管理画面のメニュー修正
  19. リストアクションの追加
  20. 動作モードの追加とモーダルウィンドウの表示
  21. 外部Web APIとの連携
  22. 権限とロール
Clone this wiki locally