Как подключить фильтр для перехвата get_post_meta при изменении вывода произвольного поля?

8 нояб. 2013 г., 14:28:58
Просмотры: 20.1K
Голосов: 9

Как подключить фильтр для перехвата get_post_meta при изменении вывода произвольного поля?

У меня есть произвольное поле (метаданные) в записи следующего вида:

<!--:de-->Nominale spanning<!--:--><!--:zh/cn-->额定电压<!--:--><!--:en-->Arrester Accessories<!--:-->

Мне нужно получить переведенный вывод этих данных, поэтому я хочу узнать, как подключиться к "get_post_meta" перед выводом метаданных.

Вот что я пытался сделать несколько дней, но безуспешно:

function getqtlangcustomfieldvalue($metadata, $object_id, $meta_key, $single){
    $fieldtitle = "fields_titles";
    if($meta_key == $fieldtitle && isset($meta_key)){
         // здесь происходит перехват, но значение не передается
    }
}
// Указываем 4 аргумента для этого фильтра в последнем параметре
add_filter('get_post_metadata', 'getqtlangcustomfieldvalue', 10, 4);
1
Комментарии

То, что вы делаете, должно работать. Какое "значение" не было передано?

s_ha_dum s_ha_dum
8 нояб. 2013 г. 17:35:59
Все ответы на вопрос 3
1
17

После долгих экспериментов с этим, я думаю, что нашел довольно хорошее решение. Я понимаю, что прошло больше года с момента вашего вопроса, но это меня беспокоило, и до сих пор я не мог найти подходящего решения.

Проблема в том, что функция get_post_metadata не позволяет получить текущее значение. Это означает, что вы не можете преобразовать значение, а только заменить его. Мне нужно было добавить содержимое к метаполю, а там, где оно выводилось, не было возможности использовать фильтры.

Вот мое решение, адаптированное под этот вопрос:

function getqtlangcustomfieldvalue($metadata, $object_id, $meta_key, $single){

    // Основной момент - добавьте дополнительные проверки, если нужно (post_type и т.д.)
    $meta_needed = 'fields_titles';
    if ( isset( $meta_key ) && $meta_needed == $meta_key ){
        remove_filter( 'get_post_metadata', 'getqtlangcustomfieldvalue', 100 );
        $current_meta = get_post_meta( $object_id, $meta_needed, TRUE );
        add_filter('get_post_metadata', 'getqtlangcustomfieldvalue', 100, 4);

        // Делайте что нужно со значением метаполя - переводите, добавляйте и т.д.
        // $current_meta = qtlangcustomfieldvalue_translate( $current_meta );
        // $current_meta .= ' Добавленный текст';
        return $current_meta;
    }

    // Возвращаем оригинальное значение, если проверка не пройдена
    return $metadata;

}

add_filter( 'get_post_metadata', 'getqtlangcustomfieldvalue', 100, 4 );

Это позволит сохранить все остальные фильтры get_post_metadata и даст возможность модифицировать исходное значение.

17 янв. 2015 г. 18:55:06
Комментарии

Если вы получаете сериализованный массив из метаданных записи, возможно, вам нужно вернуть значение внутри нового массива. Пример: return array( $metadata );

Pablo S G Pacheco Pablo S G Pacheco
23 дек. 2022 г. 00:18:37
3

У меня была такая же проблема, и, используя ваш код выше, вот как я ее решил:

function getqtlangcustomfieldvalue($metadata, $object_id, $meta_key, $single) {
    $fieldtitle="fields_titles";
    if($meta_key==$fieldtitle&& isset($meta_key)) {
        //используем $wpdb для получения значения
        global $wpdb;
        $value = $wpdb->get_var( "SELECT meta_value FROM $wpdb->postmeta WHERE post_id = $object_id AND  meta_key = '".$meta_key."'" );

        //делаем что-то с $value

        return $value;
    }
}
add_filter('get_post_metadata', 'getqtlangcustomfieldvalue', 10, 4);

Я пробовал использовать apply_filters, get_metadata, get_post_meta непосредственно внутри функции, но они не позволяли манипулировать результатом, поэтому я прибегнул к использованию $wpdb.

12 сент. 2014 г. 19:31:22
Комментарии

Внимание, это приведет к тому, что отфильтрованные метаданные не будут кэшироваться в объектном кеше. Решение от @joshcanhelp не страдает этой проблемой, так как по-прежнему использует get_post_meta()

Z. Zlatev Z. Zlatev
19 мая 2018 г. 12:55:57

Это может привести к DDoS-атаке на ваш сервер базы данных.

svandragt svandragt
29 янв. 2019 г. 13:31:54

Верно насчет кэширования. get_post_meta действительно лучше использовать, но в 2014 году этот метод не работал внутри функции.

Что касается падения сервера БД - вряд ли. Запрос get_var эквивалентен get_post_meta и представляет собой простой запрос. Даже если он выполняется сотни раз на странице, это не приведет к падению сервера. Это решение работает в продакшене с 2014 года без каких-либо проблем.

forlogos forlogos
30 янв. 2019 г. 14:32:20
0

Вот моё решение для фильтрации метаданных записей. Оно вызывает пользовательскую функцию для выполнения необходимых манипуляций с данными.

public function filter_post_meta($metadata = null, $object_id, $meta_key, $single)
{
    $meta_cache = wp_cache_get($object_id, 'post_meta');

    if ( !$meta_cache ) {
        $meta_cache = update_meta_cache( 'post', array( $object_id ) );
        $meta_cache = $meta_cache[$object_id];
    }

    if ( ! $meta_key ) {
        foreach ($meta_cache as $key => $val) {
            foreach ($val as $k => $v) {
                $meta_cache[$key][$k] = yourCustomFunction($v);
            }
        }

        return $meta_cache;
    }

    if ( isset($meta_cache[$meta_key]) ) {
        if ( $single ) {
            $value = maybe_unserialize( $meta_cache[$meta_key][0] );

            return yourCustomFunction($value);
        } else {
            return array_map(
                'maybe_unserialize',
                array_map(
                    'yourCustomFunction',
                    $meta_cache[$meta_key]
                )
            );
        }
    }

    return $single ? '' : [];
}

add_filter('get_post_metadata', 'filter_post_meta', 100, 4);
12 сент. 2018 г. 11:41:30