Я отметил этот пост как WordPress, но я не совсем уверен, что это зависит от WordPress, поэтому я отправляю его на StackOverflow, а не в WPSE. Решение не обязательно должно быть специфичным для WordPress, просто PHP.
Сценарий
Я запустил веб-сайт рыбного хозяйства с несколькими записями тропической рыбы 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 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 управляет заданием cron (которое, как ложный cron, работает с ударами пользователей, но это не имеет особого значения, поскольку время не имеет значения), который запускает фильтр, найденный выше.
Обоснование запуска его на почасовой основе состояло в том, что если бы мы пытались запустить его, когда каждый пост был сохранен, это было бы в ущерб автору. Когда мы приглашаем авторов-гостей, это, очевидно, не является приемлемым способом для этого.
Проблема...
В течение нескольких месяцев у меня возникали проблемы с надежной работой этого фильтра. Я не считаю, что проблема связана с самим фильтром, но с одной из функций, которые позволяют фильтровать, то есть задание cron, или функцию, которая выбирает, какие сообщения фильтруются, или функцию, которая подготавливает списки слов и т.д. Для фильтр.
К сожалению, диагностировать проблему довольно сложно (что я вижу), благодаря чему она работает в фоновом режиме и только на почасовой основе. Я пытался использовать функцию Word update_option
WordPress (которая в основном записывает простое значение базы данных) для проверки ошибок, но мне не повезло - и, честно говоря, я довольно смущен относительно того, где проблема лежит.
Мы закончили тем, что веб-сайт работал без фильтра. Иногда это работает, иногда это не так. В результате у нас теперь имеется довольно много профилей видов, которые неправильно фильтруются.
Что мне нравится...
Я в основном ищу совет по наилучшему способу работы с этим фильтром.
Ответ на задание Cron? Я могу настроить файл .php
, который запускается каждый день, что не будет проблемой. Как определить, какие сообщения нужно отфильтровать? Какое влияние это окажет на сервер в момент его запуска?
В качестве альтернативы, является ли страница администратора WordPress ответом? Если бы я знал, как это сделать, то что-то вроде строки страницы, использующей AJAX, которая позволяла мне выбирать столбы для запуска фильтра, была бы идеальной. Там плагин под названием AJAX Regenerate Thumbnails
работает так, может быть, это будет наиболее эффективным?
Соображения
- Размер базы данных/информации, затрагиваемой/прочитанной/записанной
- Какие сообщения отфильтрованы
- Влияние фильтра на сервер; особенно учитывая, что я, похоже, не могу увеличить предел памяти WordPress за 32 МБ.
- Является ли фактический фильтр эффективным, эффективным и надежным?
Это довольно сложный вопрос, и я неизбежно (поскольку я был отвлечен примерно 18 раз коллегами в этом процессе) не учитывал некоторые детали. Пожалуйста, не стесняйтесь исследовать меня для получения дополнительной информации.
Спасибо заранее,