Разрешить только одно сообщение с определенным значением мета

Я использую настраиваемое мета-поле, чтобы указать, какой пост будет отображаться как признак на первой странице.

Это мета-поле является истинным / ложным значением, объявленным через ACF.

Я хочу, чтобы это условие применялось только к одному сообщению, то есть когда пользователь объявляет сообщение как «признанный» и сохраняет его, все остальные (теоретически только последние), которые имеют это метазначение, должны быть повернуты " выкл».

Чтобы достичь этого, я объявил функцию, прикрепленную к действию «save_post», которая превращается в «ложное» это конкретное значение метаданных для более старых опубликованных сообщений.

Это мое приближение, но есть кое-что, что мне не хватает, потому что он не работает вообще.

function only_one_agenda_featured( $post_id ) { // If this isn't a 'agenda' post, don't update it. if ( 'agenda' != $post->post_type ) { return; } // Stop when it is an autosave if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) { return; } // Prevent quick edit from clearing custom fields if (defined('DOING_AJAX') && DOING_AJAX) { return; } $post_meta_value = get_post_meta( $post_id, 'agenda_featured', TRUE ); if ( $post_meta_value == '1' ) { $args = array( 'meta_key' => 'agenda_featured', 'meta_value' => '1', 'post_type' => 'agenda', 'post__not_in' => array($post_id), ); $posts_to_update = get_posts( $args ); foreach ( $posts_to_update as $post_to_update ) { update_post_meta( $post_to_update->ID, 'agenda_featured', '0', '1' ); } } } add_action( 'save_post', 'only_one_agenda_featured' ); 

Любая помощь будет оценена.

Я хочу, чтобы это условие применялось только к одному сообщению, то есть когда пользователь объявляет сообщение как «признанный» и сохраняет его, все остальные (теоретически только последние), которые имеют это метазначение, должны быть повернуты " выкл».

Затем вы можете попытаться сохранить только один и тот же идентификатор сообщения.

Тогда вам не нужно загрязнять мета-таблицу сообщений несколькими ложными значениями.

Первая проблема заключается в том, что $post не входит в сферу вашего обратного вызова. Вам нужно изменить код, чтобы потянуть его:

 function only_one_agenda_featured( $post_id, $post ) { // ... } add_action( 'save_post', 'only_one_agenda_featured' ,10, 2); 

Учитывая это изменение, все должно работать лучше, но код слишком сложный. Если вам не нужна история старых agenda_featured сообщений, все, что вам нужно сделать, это удалить старое поле и затем установить новый.

 function only_one_agenda_featured( $post_id, $post ) { // If this isn't a 'agenda' post, don't update it. if ( 'agenda' != $post->post_type ) { return; } // Stop when it is an autosave if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) { return; } // Prevent quick edit from clearing custom fields if (defined('DOING_AJAX') && DOING_AJAX) { return; } if (!empty($_POST['agenda_featured']) && true == $_POST['agenda_featured']) { // delete delete_metadata ( 'agenda', null, 'agenda_featured', null, true ); // and insert add_post_meta( $post_id, 'agenda_featured', true); } } add_action( 'save_post', 'only_one_agenda_featured' ,10, 2); 

Вы можете еще больше упростить это, используя привязку типа post-type :

 3580 do_action( "save_post_{$post->post_type}", $post_ID, $post, $update ); 

Что-то вроде:

 function only_one_agenda_featured( $post_id, $post ) { // Stop when it is an autosave if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) { return; } // Prevent quick edit from clearing custom fields if (defined('DOING_AJAX') && DOING_AJAX) { return; } if (!empty($_POST['agenda_featured']) && true == $_POST['agenda_featured']) { // delete delete_metadata ( 'agenda', null, 'agenda_featured', null, true ); // and insert add_post_meta( $post_id, 'agenda_featured', true); } } add_action( 'save_post_agenda', 'only_one_agenda_featured' ,10, 2); 

Вы можете сделать удаление / сохранение немного более эффективным с помощью прямого SQL, но я придерживался функций Core, таких как хороший мальчик;)