web-dev-qa-db-ja.com

アンパサンドをエスケープせずに投稿を更新しますか?

wp_update_post()は投稿のpost_contentにあるすべてのアンパサンドをエスケープすることがわかりました。アンパサンドを&に変換せずに投稿を更新しようとしています。 (私は平文のURL(リンクではなくリンク)を投稿のpost_contentフィールドに追加する必要があります)。それで、私はエスケープを無効にしてwp_update_post()を使う方法、あるいはその代わりにおそらく他の関数を使う方法を見つけようとしています。

1つのアプローチは$wpdbを直接行使することですが、それは私にとって最後の手段のようには思えません。

私が行った1つの観察は、あなたが管理インタフェースを通して投稿を編集するために "Text"ビューを使うなら、それらが&に変換されることなしにpost_contentにアンパサンドを首尾よく追加できることです。しかし、Wordpressがこれを達成する方法を見つけるためにコードをたどるのに時間がかかります。 WPがこれを達成する方法を誰かが知っていますか?

最終的に、私の質問は、アンパサンドを "無効"にして投稿を更新する最善の方法は何ですか?

2
rinogo

これは正しいことです。Adminセクションの更新は、&&に変更しませんが、wp_update_post()関数(3772行目の / wp-includes/post.php にあります)ただし、ユーザーが機能unfiltered_htmlを持っていない場合に限ります。

3820行目に示されているように、私はこれを少し調べて、wp_update_post()が内部でwp_insert_post()を呼び出すことを発見しました。

return wp_insert_post( $postarr, $wp_error );

wp_insert_post()が行3227でsanitize_post()を呼び出します

$postarr = sanitize_post( $postarr, 'db' );

次に2176行目で、このフィルタは&&に変更します。

$value = apply_filters( "{$field_no_prefix}_save_pre", $value );

私はタイトルと同じ問題に直面しているので、特にcontent_save_preまたは私の場合title_save_preと呼ばれるフィルタがあります。

それでは、 / wp-admin/post.php を使った管理ページに行きましょう。

実際の保存は205行目にあります。

$post_id = edit_post();

edit_post()関数は208行目の / wp-admin/includes/post.php にあります。

function edit_post( $post_data = null ) {

実際の更新は382行目で行われています

$success = wp_update_post( $post_data );

これは、Wordpressが同じwp_update_post()関数を内部的に使用していることを示しています。

Wordpressの管理者によって使用されていない 'wp_filter_kses'という名前のフィルタがあり、これが大きな違いを生み出しています。あなたはそれを使用してそれを削除することができますが:

remove_filter('content_save_pre', 'wp_filter_kses');

または私の場合

remove_filter('title_save_pre', 'wp_filter_kses');

@rinogoが述べたように、kses_remove_filters()を使ってすべてのksesフィルタを削除することができます。

ただし、これらのフィルタは、ユーザーが "unfiltered_html"の機能を持っているかどうかを確認した後、1934行目で / wp-includes/kses.php によって設定されます。

    if ( ! current_user_can( 'unfiltered_html' ) ) {
    kses_init_filters();
    }

kses_init_filters()が呼び出された場合、投稿を更新しようとしているユーザーは十分に信頼されておらず、適切な機能を持っていません。

フィルタを削除するのではなく、認証を正しく処理することをお勧めします。

1
Basil Banbouk

WPの管理インターフェースがこれをどのように処理するのかわかりません(たとえば、質問で参照したシナリオ)が、これを達成する方法が見つかりました。

//Disable KSES
kses_remove_filters();          

$update_rval = wp_update_post($updates);

//Reenable KSES
kses_init_filters();

"kses"関数はWordpressの悪意あるコードに対する防御の一部です。だから、あなた自身の責任でこのアプローチを使ってください。 KSESはアンパサンドをエスケープするだけでなく、多くのを実行します。 $updatesに信頼できるデータが含まれている場合(私の場合のように)、おそらくこのアプローチを使用しても安全です。

0
rinogo