アルファサード株式会社 代表取締役 野田 純生のブログ


PHPerのための Movable Type 講座(その7)


公開日 : 2014-04-18 12:38:07


引き続き、class BaseObject編(abstract class BaseObject extends ADOdb_Active_Record)。

BaseObject(mt/php/lib/class.baseobject.php)は abstract class なので、継承してサブクラスを作り、そこから利用します。お作法的には、MT::Fooオブジェクトを作った場合、 class.mt_foo.php という名前でファイルを作り、以下のように定義。

<?php
require_once("class.baseobject.php");    
class Foo extends BaseObject
{
    public $_table = 'mt_foo';
    protected $_prefix = "foo_";
}
?>

カスタムフィールド対応の場合は、ADODB_Active_Record::ClassHasMany を追加します。

<?php
require_once("class.baseobject.php");    
class Foo extends BaseObject
{
    public $_table = 'mt_foo';
    protected $_prefix = "foo_";
}
ADODB_Active_Record::ClassHasMany('Foo', 'mt_foo_meta','foo_meta_foo_id');  
?>

Load

引数には、WHERE分か、数字(ID)を渡す。戻り値は真偽値(true or false)。ロードされたオブジェクトはそのままクラスインスタンスに代入されます。

require_once( 'class.mt_entry.php' );
$entry = new Entry;
$entry->Load( 1 );
var_dump( $entry );

上記の例では、IDを渡しているが、WHERE文を渡すこともできます。 但し、代入されるのは単一のオブジェクトになることに注意。つまり、以下のWHERE文に該当するmt_entryレコードが複数あっても、単一のオブジェクトしか取得できません。

require_once( 'class.mt_entry.php' );
$entry = new Entry;
$entry->Load( 'entry_status=2' );

オブジェクトの各カラムの値は以下のように取得(例:記事のタイトル)。

echo $entry->title;

Find

複数のオブジェクトを取得するには、LoadではなくFindを使います。以下を実行すると、$entriesにはオブジェクトの配列が格納されます。

require_once( 'class.mt_entry.php' );
$entry = new Entry;
$entries = $entry->Find( 'entry_status=2' );
var_dump( $entries );

Findの第4引数に、orderやlimitなどのオプションを配列で渡すことができます。join、distinctなどの指定も可。

require_once( 'class.mt_entry.php' );
$entry = new Entry;
$entries = $entry->Find( 'entry_status=2', FALSE, FALSE, array( 'limit' => 1 ) );
var_dump( $entries );

もうちょっと複雑な例。テーブルのJOIN。

$tag_id = 1;
$where = 'entry_status=2';
$where .= " AND objecttag_object_id = entry_id ";
$where .= " AND objecttag_tag_id = ${tag_id} ";
$extra = array( 'limit' => $lastn, 'offset' => $offset, );
$join = array();
$join[ 'mt_objecttag' ] = array( 'condition' =>
                                            "objecttag_tag_id=${tag_id}" );
$extra[ 'join' ] = $join;
$entry = new Entry;
$entries = $entry->Find( $where, false, false, $extra );

以下のように、$mt->db()->SelectLimitでも記事のリストが得られますが、得られるのはSQL実行結果がオブジェクトではないことに注意してください。

require_once( 'class.mt_entry.php' );
$entries = $mt->db()->SelectLimit( 'select mt_entry.*
                                    from mt_entry where entry_status=2', 10, 0 );
$count = $entries->RecordCount();
for ( $i = 0; $i < $count; $i++ ) {
    $entries->Move( $i );
    $_entry = $entries->FetchRow();
    $entry = new Entry;
    $entry->Load( $_entry[ 'entry_id' ] );
        // idからオブジェクトを取得
    var_dump( $entry );
}

class BaseObjectの話しと離れてしまいますが、そもそもSQL文をそのまま実行する場合は $mt->db()->execute を使います。

$mt->db()->execute( $sql );

Save( Update )

MTのダイナミックパブリッシングは表示に利用されていて管理機能はないけれども、以下のようにすればちゃんと新規記事が登録できます。

require_once( 'class.mt_entry.php' );
$entry = new Entry;
$entry->set_values( array( 'blog_id' => 1,
                                       'author_id' => 1,
                                       'status' => 1,
                                       'current_revision' => 0,
                                       'title' => 'This is it.' ) );
$entry->Save();

has_column

カラムが存在するかどうか。'field.basename' でカスタムフィールドの存在チェックも可。

require_once( 'class.mt_entry.php' );
$entry = new Entry;
$has_text = $entry->has_column( 'text' );
// true

install_meta

ちょっと長いコードになるんですけど、独自カスタムフィールドをプラグインで以下のように追加した時、

global $customfield_types;
$customfield_types[ 'book' ] = array(
    'field_html' => array (
        'default' => 'customfield_html_customobject',
        'author' =>  'customfield_html_customobject_author',
    ),
    'column_def' => 'vinteger_idx',
);
$customfield_types[ 'book_multi' ] = array(
    'field_html' => array (
        'default' => 'customfield_html_customobject_multi',
        'author' =>  'customfield_html_customobject_multi_author',
    ),
    'column_def' => 'vchar_idx',
);
$customfield_types[ 'book_group' ] = array(
    'field_html' => array (
        'default' => 'customfield_html_customobject',
        'author' =>  'customfield_html_customobject_author',
    ),
    'column_def' => 'vinteger_idx',
);

カスタムフィールドをBaseObject::install_metaしておかないと、$entry_meta_info = Entry::get_meta_info( 'entry' ); みたいに(記事カスタムフィールドを取得)した時に、認識されないので。つまり、カスタムフィールド(メタ情報)を動的にオブジェクトに追加するために呼ぶメソッドです。

$mt = MT::get_instance();
$ctx =& $mt->context();
require_once( 'class.mt_field.php' );
$_field = new Field();
$where = "field_customobject=1";
$customfields = $_field->Find( $where, FALSE, FALSE, array() );
foreach ( $customfields as $field ) {
    $type = $field->field_type;
    if ( strpos( $type, 'book' ) === 0 ) {
        $col_type = $customfield_types[ $type ][ 'column_def' ];
        if ( $col_type ) {
            BaseObject::install_meta( $field->field_obj_type, 'field.' . $field->field_basename, $col_type );
        }
    }
}

そろそろ、プラグインに行ってもいいかなー? (いいとも?)



このブログを書いている人
野田純生の写真
野田 純生 (のだ すみお)

大阪府出身。ウェブアクセシビリティエバンジェリスト。 アルファサード株式会社の創業者であり、現役のプログラマ。経営理念は「テクノロジーによって顧客とパートナーに寄り添い、ウェブを良くする」。 プロフィール詳細へ