[MovableType]mt_sessionテーブルのsession_dataを解析(アンシリアライズ)する方法


↓こんなの
 SERG       ^BH   >   ^Radd_category_id_54-        -       
^Pauthored_on_time-  01:18:12   ^Radd_category_id_48-       ^Lcustom_prefs- 
  !title,text,tags,category,feedback
これは、MovavleTypeの MT::Serializeクラス(lib/MT/Serialize.pmファイル)の"_macrofreeze"という謎のサブルーチンによってシリアライズされたフォーマットです。
これを解析(アンシリアライズ)するのは面倒くさいので、何か逃げ道がないか考えてみました。

MT::Serializeのシリアライゼーションの方法は変更できる!

公式ドキュメントに答えがありました。
Movable Type オブジェクト・リファレンス- MT::Serialize
解説
このパッケージは、Movable Typeで使えるシリアライゼーション・メソッドを抽象化するためのパッケージです。
シリアライゼーションの方法は、環境変数Serializerで指定します。
現時点で使えるシリアライゼーションの方法は、"MT"と"Storable"です。
変数をデバグして調べてみたら、デフォルトは"MT"のようです。これを変更すればよいのですね。
早速、mt-config.cgiを開いて環境変数Serializerを追記してみました。

#==== Serializer ====
Serializer MTJ
シリアライザを"MTJ"に変えると、_freeze_mt_jsonメソッドによってシリアライズされます。
(他にも"JSON"や"Storable"なども選択できるようなのですが、何故かエラーで動きませんでした。)

具体的に言うと、mt_session.session_dataが下記のようなJSON形式になります。
 SERG       ^D{"authored_on_time":"02:00:26","":"","add_category_id_54":"","excerpt":"","custom_prefs":"title,text,tags,category,feedback","add_category_id_48":"","
最初に見た謎のフォーマットと比べて、こっちはJSONだけに目で見ても構造がわかります。
なんとかなりそうな気がしてきました。

このデータはMT::Serializeクラスにある下記メソッドでアンシリアライズできそうです。
実際やってみたらできました。
sub _thaw_mt_4 {            # JSON
    my ($frozen) = @_;
    return unless substr( $frozen, 0, 4 ) eq 'SERG';

    my $thawed;
    my $pos = 12;           # skips past signature and version block

    require JSON;
    $thawed = JSON::decode_json( substr( $frozen, $pos ) );
    $thawed = {} unless defined $thawed;
    \$thawed;
}
ついに「自動保存」された記事のデータを取得することができそうです!
これはすごい!
カテゴリ: