Поддержка Проблемы и решения Как запретить создавать теги Участникам и Авторам?

  • Решено Kolya Korobochkin

    (@korobochkin)


    Как убрать из WordPress возможность создания новых тегов (меток) при сохранении поста?

    Варианты с одним лишь remove_meta_box не предлагать, потому что это лишь убирает блок с тегами, через POST запрос, через WP приложение для телефона или через XML RPC теги по прежнему можно будет создавать (добавлять).

    Я рылся в исходниках, в функции wp_insert_post вызывается sanitize_post, в которой вроде что-то есть, но я не разобрался.

    В какой файл рыть, какие фильтры использовать?

    Зачем я все это делаю?
    Сайт с открытой регистрацией. После регистрации пользователи могут писать посты, однако, с большой периодичностью сыпется вот такой спам http://cl.ly/XIJn

Просмотр 15 ответов — с 16 по 30 (всего 31)
  • Так, я начала чтение в этом файле с той строки, на которую вы указали и дошла до функции wp_insert_term

    А где ты нашла wp_insert_term?
    Я из wp_insert_post в итоге прихожу в function wp_set_object_terms, в которой никаких фильтров нет и она уже в БД все вставлять начинает.

    Я потеряла путь. Второй раз тоже туда пришла в wp_set_object_term. Может в таксономиях где-то.. Я их читала.

    Да, я тоже сбился. Вчера на свежую голову еще раз прошелся xdebug. Мой фильтр

    add_filter ('pre_post_tags_input', 'selena_network_pre_tags_input_filter');

    работает и внутри wp_insert_post я вижу, что до $postarr = sanitize_post($postarr, 'db'); в $postarr[‘tags_input’] есть несколько ячеек (1 под каждый тег), а уже после в этой переменной пустой массив. Следовательно внутрь:

    if ( isset( $tags_input ) && is_object_in_taxonomy($post_type, 'post_tag') )
    		wp_set_post_tags( $post_ID, $tags_input );

    мы уже не попадем (isset отдаст false), потому что дебагер показывает, что $tags_input не инициализирована, потому что в $postarr['tags_input'] было пусто.

    Теги все равно сохраняются 🙂 Видимо надо где-то в другом месте искать.

    И еще, интересно все-таки где этот массив заполняется с tags_input.
    Функцию wp_insert_post же кто-то вызывает и передает ей параметры, вот наверное там и берутся все эти значения 🙂

    Константина бы спросить (написал ему на почту уже давно) или Сергея, но они видимо заняты.

    Метки похоже в tax_input записываются и поэтому pre_post_tax_input фильтр запрещает их создание.

    Так почему tax_input, если мы видим, что:

    if ( isset( $tags_input ) && is_object_in_taxonomy($post_type, 'post_tag') )
    	wp_set_post_tags( $post_ID, $tags_input );

    Здесь $tags_input.

    Ну а дальше

    // New-style support for all custom taxonomies.
    	if ( ! empty( $postarr['tax_input'] ) ) {
    		foreach ( $postarr['tax_input'] as $taxonomy => $tags ) {
    			$taxonomy_obj = get_taxonomy($taxonomy);
    			// array = hierarchical, string = non-hierarchical.
    			if ( is_array( $tags ) ) {
    				$tags = array_filter($tags);
    			}
    			if ( current_user_can( $taxonomy_obj->cap->assign_terms ) ) {
    				wp_set_post_terms( $post_ID, $tags, $taxonomy );
    			}
    		}
    	}

    Для всех таксономий и для меток тоже вот это сработает wp_set_post_terms( $post_ID, $tags, $taxonomy );

    Может она два раза подряд метки сохраняет?

    Я опять из тагов попала в

    $term = apply_filters( 'pre_insert_term', $term, $taxonomy );

    за 4 шага примерно.

    wp_set_post_tags
    wp_set_post_terms
    wp_set_object_terms
    wp_insert_term

    if ( !$term_info = term_exists($term, $taxonomy) ) {
    2643	                        // Skip if a non-existent term ID is passed.
    2644	                        if ( is_int($term) )
    2645	                                continue;
    2646	                        $term_info = wp_insert_term($term, $taxonomy);
    2647

    }

    Если терма нет, то он создается, а там фильтр.

    Чудеса. Каким образом мы в if ( !empty($tax_input) ) попадаем внутри wp_insert_post, если $tax_input = <uninitialized> в дебагере написано 🙂

    Допустим вот это использовать будем.

    $term = apply_filters( 'pre_insert_term', $term, $taxonomy );

    Нам надо выйти из функции, поэтому смотрим где есть ретурны:

    if ( is_wp_error( $term ) ) {
    return $term;
    }

    Смотрим функцию is_wp_error:

    function is_wp_error($thing) {
      if ( is_object($thing) && is_a($thing, 'WP_Error') )
        return true;
      return false;
    }

    Окей, значит нам нужно отдать какой-то объект. Небольшое блуждание по коду, видим, что этим объектом может быть некий WP_Error. Пишем свое ведерко кода:

    function selena_network_pre_insert_term_filter ($term, $taxonomy) {
    	return new WP_Error ('selena_network_user_is_not_allowed_to_create_taxonomies', __("Selena Network: This user is not allowed to create taxonomies."));
    }
    add_filter ('pre_insert_term', 'selena_network_pre_insert_term_filter', 10, 2);

    Как-то костыльно вроде? 🙂 Получается теги проходят как минимум 5 функций и только на вызове 5-ой мы можем сказать, что нельзя создавать теги — не эффективно, хотя может я за излишнюю оптимизацию и пытаюсь писать что-то вроде:

    if( ! is_null($var) )
      $var = null;

    🙂

    Мой финальный вариант. Если пользователь не может редактировать чужие посты (по умолчанию это редакторы и администраторы), то новая таксономия не будет создаваться.

    function selena_network_pre_insert_term_filter ($term, $taxonomy) {
    	if (! current_user_can ('edit_others_posts')) {
    		return new WP_Error ('selena_network_user_is_not_allowed_to_create_taxonomies', __("Selena Network: This user is not allowed to create taxonomies.", 'selena_network'));
    	}
    	return $term;
    }
    add_filter ('pre_insert_term', 'selena_network_pre_insert_term_filter', 10, 2);

    Метабокс с тегами я решил не прятать, в принципе, существующие теги можно добавлять 🙂

    Также я выключил возможность не редакторам менять статус комментариев и трекбеков (пингов), через фильтр, который есть в функции wp_insert_post:

    function selena_network_wp_insert_post_data_filter ($data, $postarr) {
    	if (! current_user_can ('edit_others_posts')) {
    		$data['ping_status'] = get_option ('default_ping_status');
    		$data['comment_status'] = get_option ('default_comment_status');
    	}
    	return $data;
    }
    add_filter ('wp_insert_post_data', 'selena_network_wp_insert_post_data_filter', 10, 2);

    А не подскажете как полностью отключить поддержку тегов для поста для всех?

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

    Спасибо, что откликнулись. Я хотел полностью отключить теги на сайте. нашел вот такой код

    function unregister_taxonomy(){
        register_taxonomy('post_tag', array());
    }
    add_action('init', 'unregister_taxonomy');

    Не, я не особо разбираюсь как там в ядре это все устроено, но интуиция подсказывает, что этот код совсем не то что надо.

    Если у тебя сайт с закрытой регистрацией (или регистрация открыта, но люди не могут писать посты), то забей и просто убери из шаблона вывод тегов. Иначе есть риск нагородить костылей и могут появиться дыры и т. п. Если сайт с открытой регистрацией и пользователи могут публиковать посты, то можно взять мой вариант, заменив capability на более подходящую (плюс не забываем, что как и в первом варианте, теги можно просто не выводить в шаблоне).

    У меня как раз авторы только и пишут на сайте. Как раз из-за них я полностью убираю теги. А то они и так путаются в интерфейсе, а теги полностью мне не нужны. Они начинают их заполнять всяким шлаком, раздувают БД. Начинают тупить задавать кучу ненужных вопросов.

    Как я понимаю представленный мной код просто удаляет регистрацию таксономии «Теги».

Просмотр 15 ответов — с 16 по 30 (всего 31)
  • Тема «Как запретить создавать теги Участникам и Авторам?» закрыта для новых ответов.