Movable Type のData APIから、カスタムフィールドのデータを含む記事を投稿する(php)

Movable Type のData APIはいろいろとデータのやり取りができて便利です。

通常の記事データの投稿や取得はあまり悩みませんが、カスタムフィールドを含む場合、通常の記事よりも構造が深くなるため、初見では混乱する方もおるかと思います。

そこで、phpを利用して、カスタムフィールドのデータを含む記事データを投稿するコードを書いてみました。


```
postcf.php

<?php

// Definition

define("API_PATH", "<MTCGIPath><MTDataAPIScript>");
$username = 'username'; 
$password = 'password'; 
$siteId   = '<MTBlogID>';  

// Authentication
$tokens = authentication($username, $password);
$accessToken = $tokens->accessToken;


// Generate Post Data

$postData = array(
   'entry' => json_encode(array(
     'title'    => $title,
     'date'     => $date,
     'body'     => $body,
     'more'     => $more,
     'status'   => 'Draft',
     'tags'     => [word,word,word],

     'customFields' => [

        array ('basename' => '$basename1', 
            'value' => $value1,
        ),
        array ('basename' => '$basename2',
            'value' => $value2,
        ),
        array ('basename' => '$basename3',
            'value' => $value3,
        )
      ],
   )),
);

post_entry($siteId, $accessToken, $postData);

function authentication( $username, $password ) {

    $api = API_PATH . '/v3/authentication';

    $postdata = array(
        'username' => $username,
        'password' => $password,
        'clientId' => 'hogehoge',
    );

    $options = array('http' => 
        array(
            'method' => 'POST',
            'header' => array('Content-Type: application/x-www-form-urlencoded'),
            'content' => http_build_query($postdata),
        )
    );

    $response = file_get_contents($api, false, stream_context_create($options));
    $response = json_decode($response);
    return $response;
}
       
function post_entry($site_id, $token, $postdata) {
    $api = API_PATH . '/v3/sites/' . $site_id . '/entries';

    $header = array(
        'X-MT-Authorization: MTAuth accessToken=' . $token,
    );

    $options = array('http' => 
        array(
            'method' => 'POST',
            'header' => $header,
            'content' => http_build_query($postdata),
        )
    );

    $response = file_get_contents($api, false, stream_context_create($options));
}
```

最初に4点を定義しています。

* MTのData APIのスクリプトのURI
* ユーザーID
* パスワード(ウェブサービス用のパスワード)
* 記事投稿したいブログのID

Data APIのスクリプト、ブログのIDは、MTタグを利用していますが、それぞれhttp形式の文字列にしたり、IDの数字にしたり、環境に合わせて書き換えください。


```

// Definition

define("API_PATH", "<MTCGIPath><MTDataAPIScript>");
$username = 'username'; 
$password = 'password'; 
$siteId   = '<MTBlogID>';  
```

関数authenticationを利用して、MTにサインインを行い、トークンを取得します。


```
// Authentication
$tokens = authentication($username, $password);
$accessToken = $tokens->accessToken;
```

投稿用の記事データをJSON型のデータとして生成します。

$が先頭につく文字列は、それぞれ入力したい文字列に置き換えて解釈ください。

* title
 * 記事タイトル
* date
 * 記事の投稿日
* body
 * 記事の本文
* more
 * 記事の続き
* status
 * 記事のステータス。[Draft]で投稿すると下書き状態で保存される。公開したい場合は[Publish]を指定。
* tags
 * 記事のタグ
* customFields
 * カスタムフィールドのデータ。構造を一段深くして、配列を生成する

カスタムフィールドへの投稿データは、[カスタムフィールドのベースネーム]、[カスタムフィールドへ投稿したい文字列]という形で配列を生成します。


```
// generate Post data

$postData = array(
   'entry' => json_encode(array(
     'title'    => $title,
     'date'     => $date,
     'body'     => $body,
     'more'     => $more,
     'status'   => 'Draft',
     'tags'     => [word,word,word],

     'customFields' => [

        array ('basename' => '$basename1', 
            'value' => $value1,
        ),
        array ('basename' => '$basename2',
            'value' => $value2,
        ),
        array ('basename' => '$basename3',
            'value' => $value3,
        )
      ],
   )),
);

```
例として

- カスタムフィールドが3つあり、それぞれのbasenameがtest1, test2, test3 の場合

このような配列となります。

```
$postData = array(
   'entry' => json_encode(array(
     'title'    => 'テストタイトル',
     'date'     => '2015-02-14T13:00:42+09:00',
     'body'     => 'bodyテスト',
     'more'     => 'moreテスト',
     'status'   => 'Draft',

     'tags'     => ['タグ1','タグ2'],
     'customFields' => [

        array ('basename' => 'test1',
            'value' => 'テスト1のデータ',
        ),
        array ('basename' => 'test2',
            'value' => 'テスト2のデータ',
        ),
        array ('basename' => 'test3',
            'value' => 'テスト3のデータ',
        )
      ],
   )),
);

```

生成した投稿用データを、関数post_entryで投稿します。
ブログのIDを示す siteId、認証が通ったことを証明する accesToken、投稿用のデータ postDataの3点を引数として渡します。

```
post_entry($siteId, $accessToken, $postData);
```

MTの認証を行うためのauthentication関数を定義します。
エンドポイント[authentication]に対して、ユーザーIDとウェブサービス用パスワードで認証を試みます。


```
function authentication( $username, $password ) {

    $api = API_PATH . '/v3/authentication';

    $postdata = array(
        'username' => $username,
        'password' => $password,
        'clientId' => 'hogehoge',
    );

    $options = array('http' => 
        array(
            'method' => 'POST',
            'header' => array('Content-Type: application/x-www-form-urlencoded'),
            'content' => http_build_query($postdata),
        )
    );

    $response = file_get_contents($api, false, stream_context_create($options));
    $response = json_decode($response);
    return $response;
}
```

記事投稿用の関数 post_entryを定義します。
ブログID、認証済みのトークン、生成した投稿用データの配列を関数に渡して処理します。
今回はfile_get_contentsを使って投稿しました。

```
function post_entry($site_id, $token, $postdata) {
    $api = API_PATH . '/v3/sites/' . $site_id . '/entries';

    $header = array(
        'X-MT-Authorization: MTAuth accessToken=' . $token,
    );

    $options = array('http' => 
        array(
            'method' => 'POST',
            'header' => $header,
            'content' => http_build_query($postdata),
        )
    );
    $response = file_get_contents($api, false, stream_context_create($options));
}
```

投稿後のレスポンスを取得したい場合は、記事投稿後に取得できる変数$responseを利用して、任意のデータを取得して処理します。

MTのデータをData API経由でやり取りする場合は、最初に、Data APIが出力するJSONデータの形式を確認して、その構造を元に入出力すると良いでしょう。Data APIの出力サンプルは、リファレンスに記述されています。

http://www.movabletype.jp/developers/data-api/v3-reference.html

記事のJSONは以下の様な型になります。

http://www.movabletype.jp/developers/data-api/v3-reference.html#entries

以上です。