PowerCMS™
アルファサードのゴールデンウィーク休業について を追加しました。
[ブログ] PowerCMS 6 でのアップデートまとめ を追加しました。
[新着情報] 多要素認証設定画面の QR コードが表示されない問題への対策ファイル を追加しました。
[新着情報] PowerCMSクラウド 月額費用の価格改定に関する追加情報を公開します を追加しました。

PowerCMS ブログ

ホーム > PowerCMS ブログ > 技術情報 > もしもテンプレートの検索・置換でテンプレートを壊してしまった時は

2016年01月22日

もしもテンプレートの検索・置換でテンプレートを壊してしまった時は

MT、PowerCMSでテンプレートの検索・置換使っていますか? このような機能を使うときはデータベースのバックアップ必須ですよね? でもついつい安易に実行してしまうようなケースはないでしょうか。同じように逆パターンに再検索・置換できるケースならまだ良いのですが、できない場合頭を抱えてしまうことになります。

テンプレートの検索・置換画面

そんな時は以下のようなスクリプトを書いて MTの toolsディレクトリに設置して実行することで更新履歴から直前のものに戻すことができます。以下の例は検索・置換対象かどうかを考慮していませんので、実際は必要なテンプレートをもう少し指定してやる必要があります。


#!/usr/bin/perl
package MT::Tool::RevertToThePrevious;
use strict;
use warnings;
use File::Spec;
use FindBin;
use lib map File::Spec->catdir( $FindBin::Bin, File::Spec->updir, $_ ),
                                qw/lib extlib/;
use base qw( MT::Tool );

sub usage { '--debug 1' }

sub help {
    return q {
        --debug 1
    };
}

my ( $debug );

sub options {
    return (
        'debug=s'   => \$debug,
    );
}

sub main {
    my $class = shift;
    my ( $verbose ) = $class->SUPER::main( @_ );
    my $iter = MT->model( 'template' )->load_iter( { blog_id => { not => 0 },
                                                     type => { not => 'backup' } } );
    while (my $template = $iter->()) {
        my $current_revision = $template->current_revision;
        next unless $current_revision;
        $current_revision--;
        my $rev_new = _load_revision( $template,
                    { rev_number => $current_revision } );
        next unless $rev_new;
        my $obj_new = $rev_new->[ 0 ];
        my $text = $obj_new->text;
        if ( $text ) {
            $template->text( $text );
            $template->save or die $template->errstr;
        }
    }
    1;
}

sub _load_revision {
    my ( $obj, $terms, $args ) = @_;
    my $datasource = $obj->datasource;
    my $rev_class  = MT->model( $datasource . ':revision' );
    # Only specified a rev_number
    if ( defined $terms && ref $terms ne 'HASH' ) {
        $terms = { rev_number => $terms };
    }
    $terms->{ $datasource . '_id' } ||= $obj->id;
    if ( wantarray ) {
        my @rev = map { _object_from_revision( $obj, $_ ); }
            $rev_class->load( $terms, $args );
        unless ( @rev ) {
            return $obj->error( $rev_class->errstr );
        }
        return @rev;
    } else {
        my $rev = $rev_class->load( $terms, $args )
            or return $obj->error( $rev_class->errstr );
        my $array = _object_from_revision( $obj, $rev );
        return $array;
    }
}

sub _object_from_revision {
    my ( $obj, $rev ) = @_;
    my $datasource = $obj->datasource;
    my $rev_obj = $obj->clone;
    my $serialized_obj = $rev->$datasource;
    require MT::Serialize;
    my $packed_obj = MT::Serialize->unserialize($serialized_obj);
    $rev_obj->unpack_revision($$packed_obj);
    $rev_obj->modified_by( $rev->created_by );
    $rev_obj->modified_on( $rev->modified_on );
    my @changed = split ',', $rev->changed;
    return [ $rev_obj, \@changed, $rev->rev_number, $rev ];
}

__PACKAGE__->main() unless caller;

検索・置換ログ

どのテンプレートが検索・置換されたかどうかはログを見ればわかります。特定のテンプレートを id指定で処理する場合、コードを下記のようにカスタマイズします。


    my @ids = qw/ 1 2 3 4 /;
    my $iter = MT->model( 'template' )->load_iter( { id => \@ids } );

あ、このようなスクリプトを実行するときは必ずバックアップを取ってから、且つ自己責任でお願いします。バックアップ重要ですね。


カテゴリー
サイト制作全般
サポート
トラブルシューティング
技術情報

Recent Entries