WordPressプラグイン「Search Regex」を利用して置換対象に改行を追加する

f:id:tsubasa123:20170621170607j:plain

こんにちは、つばさ(@tsubasa123)です。

今回もWordPress関連のお話、ちょっと危険度高めな小ネタをお届けします。しっかりバックアップを取得しておけば大丈夫だと思いますが、基本的には自己責任でどうぞです。

Search Regex便利そう

WordPressユーザーの間では有名なプラグインみたいですが、「Search Regex」というコンテンツを一括で置換できるツールの使い方を調べていました。あれですね、WordPressへのお引っ越しの準備のうちの1つです。

ja.wordpress.org

さらっと使ってみた感想ですが、なかなか優秀な子だなーと。単純な文字列置換だけでなく、正規表現を使えるところはやはりポイント高いですね。まぁ、正規表現はあまり得意ではないのですが…

正規表現は使えるのに

改行が入れられないみたいなんですよね、というか、メタ文字全般がエスケープされてしまうのかな?具体的には、

<div class="rankstlink-r2">hogehoge</div>

このようなHTMLタグを、

<div class="rankstlink-r2">
hogehoge
</div>

このように一括で置換したかったわけです。WordPressはMySQLをデータベースに利用しているので、改行コードは「\n」に置き換えればいけるのかなーと思って色々試してみたんですが、「\n」でそのまま文字列として登録されちゃうんですよね。

セキュリティの観点からすれば厳しめに値をサニタイズ(無害化)することの大切さはわかるんですが、手作業で直すのはなんとか避けたい。専用のコードを書いて実行してもよかったのですが、今後「Search Regex」とは長い付き合いになるかもしれないので、ちょっと中身を調べてみることに。。

邪道なのはわかっていますが

コードを書き替えることでサニタイズを回避できることはなんとなく予想できていましたが、修正箇所を見つけるのに結構苦労しましたね。今回は投稿にのみ的を絞りましたが、おそらく他の箇所を同様に修正すれば固定ページもコメントもいけるんじゃないかと思います。

// /plugins/search-regex/searches/post_content.php
function replace_content ($id, $content)
{
global $wpdb;
$wpdb->query ($wpdb->prepare( "UPDATE {$wpdb->posts} SET post_content=%s WHERE ID=%d", $content, $id ) );
}

この部分を

// /plugins/search-regex/searches/post_content.php
function replace_content ($id, $content)
{
global $wpdb;
$content = str_replace('"', '\"', $content);
$wpdb->query ( "UPDATE {$wpdb->posts} SET post_content=\"{$content}\" WHERE ID=\"{$id}\";" );
}

このように修正します。これで入力値のサニタイズを回避して、直接データベースに対してUPDATE文を実行できるようになります。$wpdb->queryメソッドの中も確認しましたが、こちらではサニタイズは行われないようですね。

コードを変更した後で

正規表現を利用すれば、任意の文字の間に改行を挟むことができるようになります。

f:id:tsubasa123:20171002185348j:plain

設定やらregexやらはこんな感じ。詳しい説明は割愛。これにて解決、めでたしめでたし。

さいごに

久しぶりにプラグインのソースコードを追いましたけど、やはりコードリーディングは良い意味でも悪い意味でも勉強になりますね。「Search Regex」に関しては小規模のプラグインだったのでなんとなく全体像は把握てきました。これをベースに何か自作してみるのも面白そうかな。

今回はメタ文字のためにプラグインのソースコードを書き替えましたが、そこまでしなくても正規表現を上手に利用すれば結構色んな場面で戦えるように感じました。はてなブログからWordPressへ移行する際の「目次の問題」や「ブログカードの問題」なんかもいけそうな予感。

ではでは、最後までお付き合いいただきありがとうございました。