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

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

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

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

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

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

Просмотр 15 ответов — с 1 по 15 (всего 31)
  • Нашел фильтр pre_post_tags_input, все равно не работает 🙁 Теги добавляются, хотя я отдаю пустой массив. Через Xdebug видно, что в $tags_input приходит массив с тегами.

    function selena_network_pre_tags_input_filter ($tags_input) {
    	$output = array();
    	return $output;
    }
    add_filter ('pre_post_tags_input', 'selena_network_pre_tags_input_filter');

    Так, а в каком файле объявлен фильтр pre_post_tags_input? Что-то я не могу его найти.

    О, нашла

    Но теперь я не могу найти поле с название ‘tags_input’, у меня оно называется newtag[post_tag]. Тогда выходит, что оно имеет префикс post_.

    Да, в файле /wp-includes/post.php. В функции sanitize_post_field есть вот такая конструкция:

    https://github.com/WordPress/WordPress/blob/d088de71953cc3982f4fca926c7405411be288ad/wp-includes/post.php#L2209

    } else if ( 'db' == $context ) {
    if ( $prefixed ) {
    $value = apply_filters( "pre_{$field}", $value );
    } else {
    $value = apply_filters( "pre_post_{$field}", $value );

    Собственно, как я понял сценарий такой.

    • Вызывается функция wp_insert_post, перед тем, как вставлять данные в БД она вызывает sanitize_post для всех элементов (см. строчку 3083).
    • Функция sanitize_post вызывает для каждого элемента массива sanitize_post_field и как раз в ней есть фильтры. Как я понял только там можно подсунуть вместе массива с тегами пустой массив.

    Вероятно, пустой массив array() чем-то отличается от заполненого массива в PHP, потому что мой фильтр не срабатывает. Я знаю что apply_filters вроде как следит за тем, что отдает фильтр и тип должен совпадать. Надо проверить. Т е NULL или FALSE мы не можем отдать в нашем фильтре.

    Покрайней мере через Xdebug, как я писал выше, мне удалось понять, что в мою функцию мы все-таки попадаем (т. е. фильтр срабатывает), хоть и не всегда. Но отдать пустой массив что-то не прокатывает.

    tags_input — через xdebug на самом деле подсмотрел, как называется ячейка с тегами 🙂

    newtag[post_tag] — не понял откуда это.

    В комментарии к этому фильтру пишут, что изменяемая часть названия хука pre_{$field} ссылается на название поля в POST. Ищу название поля в html страницы добавления записи, там такого не видно..

    А как это «фильтр срабатывает не всегда»?

    Опять мало что понял. Не всегда значит, не каждый раз, как кликаю кнопку «обновить» срабатывает мой хук, иногда мимо него проходят. Там много проверок сверху, видимо где-то WP решает, что не нужно вызывать sanitize для тегов 🙂 Дебаги для пхп ужасны, var_dump () пользоваться в 100 раз удобнее, приятнее и быстрее.

    Кстати, если на строчке 2210 написать $value = array();, то теги как раз перестают сохраняться.

    видимо где-то WP решает, что не нужно вызывать sanitize для тегов :)

    Кстати, если на строчке 2210 написать $value = array();, то теги как раз перестают сохраняться.

    У вас эти две строки кода противоречат друг другу. Выходит, что она все-таки туда попадает, где объявлен этот фильтр.

    Остается только два варианта: или тип возвращается не тот или теги сохраняются в другое поле. А вы не пробовали в фильтре прочитать все значения и заменить их на пустые строки?

    на форуме вставка кода глючит.

    Надо прочитать, тогда будет ясно как и что она проверяет. Там она объявлена.

    Я посмотрела Live HTTP Headers запрос и вот что он показал

    _wpnonce=254721e79e&_wp_http_referer=%2Fwordpressrus%2Fwp-admin%2Fpost.php%3Fpost%3D2377%26action%3Dedit&user_ID=1&action=editpost&originalaction=editpost&post_author=1&post_type=post&original_post_status=publish&referredby=http%3A%2F%2Flocalhost%2Fwordpressrus%2Fwp-admin%2Fedit.php&_wp_original_http_referer=http%3A%2F%2Flocalhost%2Fwordpressrus%2Fwp-admin%2Fedit.php&post_ID=2377&meta-box-order-nonce=8a64bcb227&closedpostboxesnonce=e4496c6899&post_title=Some+Post&samplepermalinknonce=e726cd2b5d&content=Lorem+ipsum+dolor+sit+amet%2C+consectetuer+adipiscing+elit.+Donec+mollis.+Quisque+convallis+libero+in+sapien+pharetra+tincidunt.+Aliquam+elit+ante%2C+malesuada+id%2C+tempor+eu%2C+gravida+id%2C+odio.+Maecenas+suscipit%2C+risus+et+eleifend+imperdiet%2C+nisi+orci+ullamcorper+massa%2C+et+adipiscing+orci+velit+quis+magna.+Praesent+sit+amet+ligula+id+orci+venenatis+auctor.+Phasellus+porttitor%2C+metus+non+tincidunt+dapibus%2C+orci+pede+pretium+neque%2C+sit+amet+adipiscing+ipsum+lectus+et+libero.+Aenean+bibendum.+Curabitur+mattis+quam+id+urna.+Vivamus+dui.+Donec+nonummy+lacinia+lorem.+Cras+risus+arcu%2C+sodales+ac%2C+ultrices+ac%2C+mollis+quis%2C+justo.+Sed+a+libero.+Quisque+risus+erat%2C+posuere+at%2C+tristique+non%2C+lacinia+quis%2C+eros.%3C%21--more--%3E%0D%0A%0D%0A%0D%0A%0D%0ACras+volutpat%2C+lacus+quis+semper+pharetra%2C+nisi+enim+dignissim+est%2C+et+sollicitudin+quam+ipsum+vel+mi.+Sed+commodo+urna+ac+urna.+Nullam+eu+tortor.+Curabitur+sodales+scelerisque+magna.+Donec+ultricies+tristique+pede.+Nullam+libero.+Nam+sollicitudin+felis+vel+metus.+Nullam+posuere+molestie+metus.+Nullam+molestie%2C+nunc+id+suscipit+rhoncus%2C+felis+mi+vulputate+lacus%2C+a+ultrices+tortor+dolor+eget+augue.+Aenean+ultricies+felis+ut+turpis.+Lorem+ipsum+dolor+sit+amet%2C+consectetuer+adipiscing+elit.+Suspendisse+placerat+tellus+ac+nulla.+Proin+adipiscing+sem+ac+risus.+Maecenas+nisi.+Cras+semper.&wp-preview=&hidden_post_status=publish&post_status=publish&hidden_post_password=&hidden_post_visibility=public&visibility=public&post_password=&mm=10&jj=13&aa=2014&hh=16&mn=13&ss=31&hidden_mm=10&cur_mm=10&hidden_jj=13&cur_jj=28&hidden_aa=2014&cur_aa=2014&hidden_hh=16&cur_hh=22&hidden_mn=13&cur_mn=00&original_publish=Update&save=Update&post_format=0&post_category%5B%5D=0&post_category%5B%5D=2975&newcategory=New+Category+Name&newcategory_parent=-1&_ajax_nonce-add-category=e3eb35b874&tax_input%5Bpost_tag%5D=Jane%27s+Home%2Cmy_new_tag&newtag%5Bpost_tag%5D=&excerpt=&trackback_url=&metakeyselect=%23NONE%23&metakeyinput=&metavalue=&_ajax_nonce-add-meta=b53a5ab898&advanced_view=1&comment_status=open&ping_status=open&add_comment_nonce=75d09b52d5&_ajax_fetch_list_nonce=064c92434e&_wp_http_referer=%2Fwordpressrus%2Fwp-admin%2Fpost.php%3Fpost%3D2377%26action%3Dedit&post_name=%D0%B2%D0%BE%D0%BF%D1%80%D0%BE%D1%81&post_author_override=1

    Это шлется в POST /wordpressrus/wp-admin/post.php HTTP/1.1.

    Тут интересны вот эти строки с названием полей

    post_tag%5D=Jane%27s+Home%2Cmy_new_tag&newtag%5Bpost_tag%5D=

    Я не вижу тут tags_input, где он у вас появляется?

    Что-то ты в дебри какие-то полезла 🙂 Какая связь между тем, как параметр в URL называется и как называется переменная внутри функции?

    tags_input — посмотри содержимое $postarr на строчке 3084, там и будет $postarr['tags_input'].

    Далее на 3379 как раз этот элемент массива (в котором и сидят теги) как раз передается в функцию, которая выставляет эти теги для поста.

    Кстати там уже переписали код. Раньше использовалась просто переменная tags_input, а теперь на github уже просто ячейка массива. Но, это, видимо, будет в новой версии, пока по другому немного код записан.

    Значения передаются в файл php через эти параметры ‘имя=значение’. Там не url, а именно поле POST, который отправляет форма.

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

    Так, я начала чтение в этом файле с той строки, на которую вы указали и дошла до функции wp_insert_term внутри которой есть совсем другой фильтр pre_insert_term, который срабатывает при добавлении новых термов в базу данных. И с ним все прекрасно не сохраняется.

    function selena_network_pre_tags_input_filter ($tags_input) {
    	$output = array();
    	return $output;
    }
    
    add_filter ('pre_insert_term', 'selena_network_pre_tags_input_filter',10, 1);

    Не знаю, нужен там ваш array или нет..

    Теперь никакие таксономии не добавятся. Кстати, а правами пользователя вы не пробовали пользоваться?

    Тот фильтр с именем tags_input вообще не влияет на добавление тегов. Все-таки мы его неправильно вызываем..

    Фильтр tax_input тоже работает.

    add_filter( 'pre_post_tax_input', 'no_tax_input_create' );
    
    function no_tax_input_create($tax_input) {
    
        if( !isset($tax_input['post_tag']) )
            return $tax_input;
    
        $output = array();
        $tags = explode(',', $tax_input['post_tag']);
    
        foreach( $tags as $tag )
            if( term_exists( $tag, 'post_tag') )
                $output[] = $tag;
    
        $tax_input['post_tag'] = implode(',',$output);
    
        return $tax_input;
    }

    И еще, интересно все-таки где этот массив заполняется с tags_input. Там в комментариях про него ничего не пишут. Он же должен где-то брать параметры из $_POST.

    * @param array $postarr {
     *     An array of elements that make up a post to update or insert.
     *
     *     @type int    $ID                    The post ID. If equal to something other than 0,
     *                                         the post with that ID will be updated. Default 0.
     *     @type string $post_status           The post status. Default 'draft'.
     *     @type string $post_type             The post type. Default 'post'.
     *     @type int    $post_author           The ID of the user who added the post. Default is
     *                                         the current user ID.
     *     @type bool   $ping_status           Whether the post can accept pings. Default is the
     *                                         value of 'default_ping_status' option.
     *     @type int    $post_parent           Set this for the post it belongs to, if any. Default 0.
     *     @type int    $menu_order            The order it is displayed. Default 0.
     *     @type string $to_ping               Space or carriage return-separated list of URLs to ping.
     *                                         Default empty string.
     *     @type string $pinged                Space or carriage return-separated list of URLs that have
     *                                         been pinged. Default empty string.
     *     @type string $post_password         The password to access the post. Default empty string.
     *     @type string $guid'                 Global Unique ID for referencing the post.
     *     @type string $post_content_filtered The filtered post content. Default empty string.
     *     @type string $post_excerpt          The post excerpt. Default empty string.
     * }
Просмотр 15 ответов — с 1 по 15 (всего 31)
  • Тема «Как запретить создавать теги Участникам и Авторам?» закрыта для новых ответов.