WordPress как на ладони
wordpress jino

wp_kses() WP 1.0.1

Чистит строку, оставляя в ней только указанные HTML теги, их атрибуты и значения атрибутов.

Также функция убирает некоторые HTML сущности из строки.

Перед тем как использовать эту функцию нужно позаботиться о том, чтобы в строке не было экранированных слэшей, которые автоматически могут добавляться к данным в PHP (PHP's magic quotes).

KSES (рекурсивный акроним от KSES Strips Evil Scripts) — подсистема в WordPress (изначально написанная Ulf Harnhammar), предназначенная для проверки и очистки текста, введённого пользователем. Позволяет задать список допустимых тэгов, стилей и протоколов, и на основе этих параметров убрать из текста пользователя всё, что им не соответствует.

Работает на основе: wp_kses_allowed_html()
✈ 1 раз = 0.000364с = быстро | 50000 раз = 2.26с = быстро PHP 7.1.1, WP 4.7.2

Хуков нет.

Возвращает

Очищенную строку.

Использование

wp_kses( $string, $allowed_html, $allowed_protocols );
$string(строка) (обязательный)
Контент, который нужно очистить.
По умолчанию: нет
$allowed_html(массив/строка) (обязательный)

Список допустимых HTML элементов в переданном контенте. Если указать строковое значение, то оно будет означать группу предустановленных тегов:

  • post — оставит теги допустимые для постов (глобальная переменная $allowedposttags)

  • strip - вырежет все теги. Аналог функции PHP strip_tags()

  • entities — HTML сущности, как   (глобальная переменная $allowedentitynames)

  • user_description, pre_user_description — тоже что и default, только еще разрешается атрибут rel для ссылок <a>.

  • default или любая строка — список базовых допустимых тегов. Используется при очистки текста комментария: глобальная переменная $allowedtags.

По умолчанию: нет

$allowed_protocols(массив)

Протоколы, ссылки с которыми будут допущены в контенте. По умолчанию допускаются: http, https, ftp, mailto, news, irc, gopher, nntp, feed и telnet. Это все базовые протоколы, кроме javascript, который лучше запретить для сомнительных пользователей.

По умолчанию: http, https, ftp, mailto, news, irc, gopher, nntp, feed, telnet

Примеры

#1. Очистим контент, использую KSES WP

Оставим в нем только теги: 'a' ( с атрибутами 'href' и 'title' ), 'br', 'em' и 'strong'. Все остальное будет удалено:

$string = wp_unslash( $_POST['text'] );

// допустимые теги
$allowed_html = array(
	'a' => array(
		'href' => true,
		'title' => true,
	),
	'br' => array(),
	'em' => array(),
	'strong' => array()
); 

$text = wp_kses( $string, $allowed_html );

echo $text;

#2. Оставим теги, которые допустимы при комментировании:

$text = "<div>1111</div><strong>222</strong>";
$text = wp_kses( $text, 'default' );
echo $text;

// выведет
// 1111<strong>222</strong>

#3. Какие теги находятся в глобальной $allowedtags

Array(
	[a] => Array(
			[href] => 1
			[title] => 1
		)

	[abbr] => Array(
			[title] => 1
		)

	[acronym] => Array(
			[title] => 1
		)

	[b] => Array()

	[blockquote] => Array(
			[cite] => 1
		)

	[cite] => Array()

	[code] => Array()

	[del] => Array(
			[datetime] => 1
		)

	[em] => Array()

	[i] => Array()

	[q] => Array(
			[cite] => 1
		)

	[s] => Array()

	[strike] => Array()

	[strong] => Array()
)

Код wp kses: wp-includes/kses.php WP 4.8.2

<?php
function wp_kses( $string, $allowed_html, $allowed_protocols = array() ) {
	if ( empty( $allowed_protocols ) )
		$allowed_protocols = wp_allowed_protocols();
	$string = wp_kses_no_null( $string, array( 'slash_zero' => 'keep' ) );
	$string = wp_kses_normalize_entities($string);
	$string = wp_kses_hook($string, $allowed_html, $allowed_protocols); // WP changed the order of these funcs and added args to wp_kses_hook
	return wp_kses_split($string, $allowed_html, $allowed_protocols);
}

Cвязанные функции

Из метки: kses (очистка html)

Еще из раздела: Очистка данных

wp_kses 7 комментариев
  • campusboy1847 cайт: wp-plus.ru

    Классная функция smile Вопросик один, что делает в 1 примере функция array_map()? Без неё там никак?

    Ответить1.7 года назад #
    • Kama4464

      Хороший вопросик. Убрал эту строку из примера и добавил wp_unslash(), а то было немного не логично...

      Ответить1.7 года назад #
  • campusboy1847 cайт: wp-plus.ru
    $text = wp_kses( $text, 'post' );

    Не вырезает html-комментарии, не вырезает атрибут onclick у ссылок (по сути можно XXS атаку устроить, так?). Вообще не понял, что ж оно тогда вырезает laugh И почему-то var_dump($allowedposttags) не до конца показывает содержимое переменной, через определенный промежуток появляются троеточие и хватит smile хотел изучить, что ж внутри.

    Ответить1.2 года назад #
    • campusboy1847 cайт: wp-plus.ru

      И тогда зреет вопрос, как wp_insert_post очищает данные? Вроде там всякие очистки от мерзости идут, а по итогу js скрипты попадать могут. Пока не разобрался с этим делом.

      Ответить1.2 года назад #
      • Kama4464

        Куда в контент? Не должно такого быть...

        Что-то у тебя не то. Щас попробовал запустить такой код под администратором:

        echo esc_html( wp_kses( '<a href="#" onclick="alert(\'aaaaaa\');">link</a>', 'post' ) );
        
        // получил: <a href="#">link</a>
        Ответить1.2 года назад #
        • campusboy1847 cайт: wp-plus.ru

          Код:

           // Создаем массив
          $post_data = array(
             'post_title'    => $wp_post_data->title,
             'post_excerpt'  => removeHtmlComments( $wp_post_data->short_story ),
             'post_content'  => removeHtmlComments( $wp_post_data->full_story ),
             'post_status'   => $approve,
             'post_author'   => get_current_user_id(),
             'tags_input'   => $wp_post_data->tags,
             'post_category' => array( convert_category_dle_to_wp( $wp_post_data->category ) )
            );
          
          // Вставляем данные в БД
          $post_id = wp_insert_post( wp_unslash($post_data) );

          removeHtmlComments - функция из 1 регулярки, удаляю html комменты, ибо сами они не вырезаются. wp_kses тоже не помогает (у него не плохо вообще вырезать теги получается под ноль).

          А ещё, Тимур, может подскажешь куда копать. Все записи создаются с кириллистическим slug. Почему не отрабатывает cry-to-lat? При создании с админки все термы и посты создаются с латинским slug. Приходится отключать плагин и снова включать, он тогда пробегается по всем записям и конвертирует им slug. Но не трогает термы. Ума не хватает разобраться.

          P.S.: Надоело искать фильтры и хуки, как, где и что. Просто скопировал из плагина функцию транслитерации, почистил от ненужного и использую у себя в скрипте.

          Ответить1.2 года назад #
          • Kama4464

            На рабочем коде помог бы, а так ковыряться, время нет, сорри. Вчера смотрел, вроде должен срабатывать хук sanitize_title. Может конфликт какой...

            Ответить1.2 года назад #

Здравствуйте, !

Ваш комментарий