Существуют ли какие-либо фильтры / хуки для проверки пользовательского поля перед публикацией сообщения?

11

У меня есть заказное поле под названием xxxx_url. xxxx_urlдолжен быть уникальным.

Итак, прежде чем публиковать пост, я хочу убедиться, что xxxx_urlон уникален или нет? Если это не уникально, публикация сообщения должна быть отклонена.

Я попробовал publish_post. Но это не правильно, так как это срабатывает, когда мы публикуем сообщение. Я хочу запустить свой код непосредственно перед публикацией.

Я самый глупый человек
источник
1
Почему бы не установить идентификатор текущей записи в качестве уникального значения. Как: 132_urlгде 132идентификатор сообщения. Чем у вас всегда есть уникальная ценность здесь. Кроме того: пользовательские поля должны быть сохранены в save_postдействии. В этом действии вы можете проверить настраиваемое поле (если оно не пустое и имеет уникальное значение, например), и на основании этого update_post_metaили нет. Я думаю , вы могли бы также проверить пользовательские поля , и если он не имеет уникального значения, установить post-statusна draftили что - то еще, чтобы отключить публикацию. В противном случае, я думаю, вам нужен jQuery для этого.
LWS-Mo

Ответы:

5

В начале wp_insert_postфункции, которая сохраняет / обновляет сообщение, есть фильтр wp_insert_post_empty_content. По умолчанию этот фильтр проверяет, все ли поля заголовка, редактора и отрывка пусты, в этом случае процесс сохранения будет остановлен.

Однако, поскольку все поля, которые должны быть сохранены, передаются в этот фильтр, вы можете расширить этот фильтр, включив в него любой другой тест, чтобы определить, следует ли считать публикацию пустой. Это было бы что-то вроде этого:

add_filter ('wp_insert_post_empty_content','wpse312975_check_unique_url',10,2);
function wpse312975_check_unique_url ($maybe_empty, $postarr) {

  // extract custom field from $postarr, check uniqueness

  if ($unique) return false else return true;
  }

Примечание. Функция должна возвращать значение «истина», чтобы остановить процесс сохранения.

Если настраиваемое поле не уникально, вы можете также вывести предупреждение.

cjbj
источник
2
Это, вероятно, сработает, но выглядит скорее как хак, чем как решение. Я тоже это обдумал, но позже решил не публиковать, так как wp_insert_post_empty_contentсемантически предназначен для пустого контента . Сказав это, я не нашел ни одного семантически подходящего крючка для этого.
Скотт
Ну, если бы это было только для пустого заголовка и контента, не было бы фильтра для разработчиков.
CJBJ
1
Если вы сосредоточитесь меньше на простом слове «пусто», я бы сказал, что этот фильтр предназначен для проверки соответствия поста минимальным требованиям для сохранения. ОП хочет расширить минимальные требования. Возможно, фильтр должен быть назван так, wp_insert_post_valid_contentчтобы выразить это, но в остальном он находится в правильном месте.
CJBJ
@cjbj Если у вас есть такой вопрос, как вы найдете правильный фильтр? Я имею в виду, как вы нашли wp_insert_post_empty_contentфильтр?
Я самый глупый человек
1
Ну, когда вы некоторое время работали с WP, вы знаете, какая часть кода генерирует какие части администратора. Итак, вы просматриваете файл и проверяете исходный код на наличие доступных фильтров.
CJBJ
1

Как насчет использования AJAX для проверки уникальности еще до того, как отправить публикацию?

$( '#post' ).on( 'submit', function( event ) {
  event.preventDefault(); // Prevent publishing

  //Now do some AJAX Checks
  $.post( ajaxurl, data, function(response) {
    if ( response === 'success' ) {
        $( this ).off( event ).submit();
    } else {
        alert( 'The custom field must be unique' );
    }
  });
});  

Хотя код не проверен, но он должен работать. Возможно, вам придется поиграть с ним, чтобы получить желаемый результат.

Abhik
источник
0

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

Я не могу сэкономить слишком много в этом случае, потому что вы не делитесь ни одним кодом, но вот некоторый псевдокод фильтра, который будет работать:

function wp8193131_check_if_meta_value_is_unique ( $data, $postarr ) {
    // setup an uniqueness flag.
    $meta_is_unique = true;

    // check if the meta is unique and modify the `$meta_is_unique` flag accordingly.
    // {...} <- your code

    // if the meta is NOT unique keep the post status in draft.
    if ( ! $meta_is_unique ) {
        // you can force the current post to be draft until the meta value will became unique.
        $data['post_status'] = 'draft';
        // maybe, update the meta value with a hint of the fact that it's not unique.
        // or display a dashboard notice about it.
    }

    return $data;
}
add_filter( 'wp_insert_post_data', 'wp8193131_check_if_meta_value_is_unique' );

Еще одна замечательная особенность этого фильтра в том, что он отделен от вложений одним wp_insert_attachment_data.

Надеюсь, это поможет, и что бы вы ни делали, это звучит потрясающе!

Андрей
источник
2
Это не может быть хорошей идеей. Что если $data['post_status']есть publishи пользователь обновляет его? Разве создание поста не draftсоздаст 404проблему для этого поста?
Скотт
@Scott Другими словами, если опубликованное сообщение обнаруживает при сохранении, что его мета-значение не является уникальным, публикация публикации должна быть отклонена, и публикация должна быть составлена. Опять же, я не знаю, насколько важно это мета-значение, но если это тип данных сортировки или что-то существенное, тогда статус сообщения должен быть черновым (что не означает проблему 404, это просто говорит о том, что сообщение было удалился от публики)
Андрей
-1

Чек должен идти в wp_insert_post. Этот хук срабатывает всякий раз, когда сообщение публикуется или редактируется.

Там вы можете выполнить пользовательский запрос, чтобы проверить, есть ли какое-либо сообщение с таким же xxxx_urlзначением или нет.

add_action('wp_insert_post', function($post_id) {
    $meta_key = 'xxxx_url';
    $meta_value = get_post_meta($post_id, $meta_key, true);
    $query = new WP_Query([
        'post_type' => get_post_type($post_id),     // This might be unnecessary, if you check `post` post type only. Or use `any`.
        'meta_query' => [
            [
                'meta_key' => $meta_key,
                'meta_value' => $meta_value,
            ]
        ]
    ]);
    if ($query->have_posts()) {
        // invalid key, post with the same value already exists
    } else {
        // valid, key was not found anywhere
    }
});
Петр Сибулка
источник
3
Как я знаю, что бы вы ни писали внутри, если публикация оператора / else будет опубликована, поскольку wp_insert_postдействие запускается после сохранения сообщения, оно не может заблокировать публикацию или вставку сообщения.
Я самый глупый человек
Таким образом, вы хотите заблокировать публикацию, если сообщение не проходит проверку? Вы не написали это в своем вопросе.
Петр Сибулька
Я четко упомянул это If it isn't unique it should reject publishing post.в своем вопросе.
Я самый глупый человек