この投稿に WordPress のタグを付けましたが、WordPress 固有のものかどうか完全にはわからないため、WPSE ではなく StackOverflow に投稿しています。ソリューションは WordPress 固有である必要はなく、単純に PHPです。
シナリオ
私は、多数の熱帯魚とエントリを含む魚飼育 Web サイトを運営しています。Species Profiles
Glossary
私たちのウェブサイトは、私たちのプロフィールを中心にしています。それらは、あなたがそれを呼ぶかもしれないように、ウェブサイトのパンとバターです.
私が達成したいと思っていることは、別の種または用語集のエントリに言及しているすべての種のプロファイルで、それらの単語をリンクに置き換えることができるということです。理想的には、これがニュース、記事、ブログ投稿でも発生することを望みます.
ほとんど1400 species profiles
とがあり1700 glossary entries
ます。私たちの種のプロファイルはしばしば長く、最後に種のプロファイルだけnumbered more than 1.7 million words
を数えます。
私が現在試み
ていること 現在、私は、filter.php
必要なことを実行する関数を持っています。コードは非常に長く、ここで完全に見つけることができます。
さらに、私の WordPress テーマfunctions.php
には、次のものがあります。
# ==============================================================================================
# [Filter]
#
# Every hour, using WP_Cron, `my_updated_posts` is checked. If there are new Post IDs in there,
# it will run a filter on all of the post's content. The filter will search for Glossary terms
# and scientific species names. If found, it will replace those names with links including a
# pop-up.
include "filter.php";
# ==============================================================================================
# When saving a post (new or edited), check to make sure it isn't a revision then add its ID
# to `my_updated_posts`.
add_action( 'save_post', 'my_set_content_filter' );
function my_set_content_filter( $post_id ) {
if ( !wp_is_post_revision( $post_id ) ) {
$post_type = get_post_type( $post_id );
if ( $post_type == "species" || ( $post_type == "post" && in_category( "articles", $post_id ) ) || ( $post_type == "post" && in_category( "blogs", $post_id ) ) ) {
//get the previous value
$ids = get_option( 'my_updated_posts' );
//add new value if necessary
if( !in_array( $post_id, $ids ) ) {
$ids[] = $post_id;
update_option( 'my_updated_posts', $ids );
}
}
}
}
# ==============================================================================================
# Add the filter to WP_Cron.
add_action( 'my_filter_posts_content', 'my_filter_content' );
if( !wp_next_scheduled( 'my_filter_posts_content' ) ) {
wp_schedule_event( time(), 'hourly', 'my_filter_posts_content' );
}
# ==============================================================================================
# Run the filter.
function my_filter_content() {
//check to see if posts need to be parsed
if ( !get_option( 'my_updated_posts' ) )
return false;
//parse posts
$ids = get_option( 'my_updated_posts' );
update_option( 'error_check', $ids );
foreach( $ids as $v ) {
if ( get_post_status( $v ) == 'publish' )
run_filter( $v );
update_option( 'error_check', "filter has run at least once" );
}
//make sure no values have been added while loop was running
$id_recheck = get_option( 'my_updated_posts' );
my_close_out_filter( $ids, $id_recheck );
//once all options, including any added during the running of what could be a long cronjob are done, remove the value and close out
delete_option( 'my_updated_posts' );
update_option( 'error_check', 'working m8' );
return true;
}
# ==============================================================================================
# A "difference" function to make sure no new posts have been added to `my_updated_posts` whilst
# the potentially time-consuming filter was running.
function my_close_out_filter( $beginning_array, $end_array ) {
$diff = array_diff( $beginning_array, $end_array );
if( !empty ( $diff ) ) {
foreach( $diff as $v ) {
run_filter( $v );
}
}
my_close_out_filter( $end_array, get_option( 'my_updated_posts' ) );
}
コードのコメントで (うまくいけば) 説明されているように、これが機能する方法は、WordPress が 1 時間ごとに cron ジョブを実行することです (これは偽の cron のようなものです - ユーザーのヒット時に機能しますが、タイミングがそうではないため、それは実際には問題ではありません)。重要) 上記のフィルターを実行します。
1 時間ごとに実行する理由は、投稿が保存されるたびに実行しようとすると、作成者に不利益をもたらすからです。ゲストの著者を巻き込むと、それは明らかに容認できる方法ではありません。
問題...
何ヶ月もの間、私はこのフィルターを確実に動作させるのに問題を抱えていました。問題はフィルター自体にあるとは思いませんが、フィルターを有効にする機能の1つ-つまり、cronジョブ、またはフィルターされる投稿を選択する機能、または単語リストなどを準備する機能にあると思います.フィルター。
残念ながら、バックグラウンドで 1 時間ごとにしか実行されないため、この問題を診断するのは非常に困難です (私には分かります)。WordPress の関数 (基本的に単純なデータベース値を書き込む) を使用してエラーをチェックしようとしてきましたがupdate_option
、うまくいきませんでした。正直なところ、問題がどこにあるのかについてかなり混乱しています。
このフィルターが正しく機能せずに、ウェブサイトを公開することになりました。うまくいくように見えることもあれば、うまくいかないこともあります。その結果、正しくフィルタリングされていない種のプロファイルがかなり多くなりました。
私が望むこと...
基本的に、このフィルターを実行するための最良の方法についてアドバイスを求めています。
Cronジョブが答えですか? .php
毎日実行されるファイルを設定できますが、それは問題になりません。どの投稿をフィルタリングする必要があるかをどのように判断しますか? 実行時にサーバーにどのような影響がありますか?
あるいは、WordPress の管理ページが答えですか? その方法を知っていれば、フィルターを実行する投稿を選択できる、AJAX を利用したページの行に沿った何かが完璧でしょう。このように機能するというプラグインがありますがAJAX Regenerate Thumbnails
、おそらくそれが最も効果的でしょうか?
考慮事項
- データベースのサイズ/影響を受ける情報/読み取り/書き込み
- フィルタリングされる投稿
- フィルターがサーバーに与える影響。特に、WordPress のメモリ制限を 32Mb を超えて増やすことはできないようです。
- 実際のフィルター自体は効率的で効果的で信頼性がありますか?
これは非常に複雑な質問であり、必然的に (その過程で同僚に約 18 回注意をそらされたため) いくつかの詳細を省略しました。詳細については、お気軽にお問い合わせください。
前もって感謝します、