diff --git a/inc/promotion-alert/package/class-veu-promotion-alert.php b/inc/promotion-alert/package/class-veu-promotion-alert.php index e84a3341..50ea93fb 100644 --- a/inc/promotion-alert/package/class-veu-promotion-alert.php +++ b/inc/promotion-alert/package/class-veu-promotion-alert.php @@ -5,19 +5,19 @@ class VEU_Promotion_Alert { - /** - * Constructor Define - */ - public static function init() { + /** + * Constructor Define + */ + public static function init() { add_action( 'veu_package_init', array( __CLASS__, 'option_init' ) ); add_action( 'save_post', array( __CLASS__, 'save_meta_box' ) ); - // is_singular() で判定するため wp で実行 - add_action( 'wp', array( __CLASS__, 'display_alert' ) ); - add_action( 'wp_head', array( __CLASS__, 'inline_style' ), 5 ); - add_action( 'after_setup_theme', array( __CLASS__, 'content_filter' ) ); + // is_singular() で判定するため wp で実行 + add_action( 'wp', array( __CLASS__, 'display_alert' ) ); + add_action( 'wp_head', array( __CLASS__, 'inline_style' ), 5 ); + add_action( 'after_setup_theme', array( __CLASS__, 'content_filter' ) ); } - /** + /** * HTML Allowed */ public static function kses_allowed() { @@ -112,8 +112,8 @@ public static function kses_allowed() { '!' => array(), ); } - - /** + + /** * コンテンツにかけるフィルター */ public static function content_filter() { @@ -128,140 +128,149 @@ public static function content_filter() { add_filter( 'veu_promotion_alert_content', 'wp_replace_insecure_home_url' ); } - /** - * Get Post Types - */ - public static function get_post_types() { + /** + * Get Post Types + */ + public static function get_post_types() { - // 投稿タイプの事前準備 - $post_types_default = array( - array( - 'label' => get_post_type_object( 'post' )->label, - 'name' => 'post' - ), - array( - 'label' => get_post_type_object( 'page' )->label, - 'name' => 'page', - ), - ); - $post_types_extra = array(); - $extra_post_types = get_post_types( - array( - 'public' => true, - '_builtin' => false - ), - 'objects' - ); - foreach ( $extra_post_types as $post_type ) { - $post_types_extra[] = array( - 'label' => $post_type->label, - 'name' => $post_type->name - ); - } - $post_types = array_merge( $post_types_default, $post_types_extra ); - return $post_types; - } - - /** - * Get Options - */ - public static function get_options() { - - // デフォルト値 - $default = array( - 'alert-text' => '', - 'alert-content' => '', - 'alert-hook' => '', - ); - - // オプション取得 - $options = get_option( 'vkExUnit_PA' ); - $options = wp_parse_args( $options, $default ); - - // 投稿タイプ毎に初期化 - $post_types = self::get_post_types(); - foreach ( $post_types as $post_type ) { - if ( empty( $options['alert-display'][ $post_type['name'] ] ) ) { - $options['alert-display'][ $post_type['name'] ] = 'hide'; - } - } - - return $options; - } - - - /** - * Add Setting Page - */ - public static function option_init() { - vkExUnit_register_setting( + // 投稿タイプの事前準備 + $post_types_default = array( + array( + 'label' => get_post_type_object( 'post' )->label, + 'name' => 'post' + ), + array( + 'label' => get_post_type_object( 'page' )->label, + 'name' => 'page', + ), + ); + $post_types_extra = array(); + $extra_post_types = get_post_types( + array( + 'public' => true, + '_builtin' => false + ), + 'objects' + ); + foreach ( $extra_post_types as $post_type ) { + $post_types_extra[] = array( + 'label' => $post_type->label, + 'name' => $post_type->name + ); + } + $post_types = array_merge( $post_types_default, $post_types_extra ); + return $post_types; + } + + /** + * Get Options + */ + public static function get_options() { + + // デフォルト値 + $default = array( + 'alert-text' => '', + 'alert-content' => '', + 'alert-hook' => '', + ); + + // オプション取得 + $options = get_option( 'vkExUnit_PA' ); + $options = wp_parse_args( $options, $default ); + + // 投稿タイプ毎に初期化 + $post_types = self::get_post_types(); + foreach ( $post_types as $post_type ) { + if ( empty( $options['alert-display'][ $post_type['name'] ] ) ) { + $options['alert-display'][ $post_type['name'] ] = 'hide'; + } + } + + return $options; + } + + + /** + * Add Setting Page + */ + public static function option_init() { + vkExUnit_register_setting( __( 'Promotion Alert', 'vk-all-in-one-expansion-unit' ), // tab label. 'vkExUnit_PA', // name attr array( __CLASS__, 'sanitize_setting' ), // sanitaise function name array( __CLASS__, 'render_setting' ) // setting_page function name ); - } - - /** - * Sanitize Space - */ - public static function sanitize_space( $input ) { - if ( preg_match( '/^(\s)+$/u', $input ) ) { - return ''; - } - return $input; - } - - /** - * Sanitize Setting - */ - public static function sanitize_setting( $input ) { - - // 投稿タイプを取得 - $post_types = self::get_post_types(); - - // 許可されたHTMLタグ - $allowed_html = self::kses_allowed(); - - // サニタイズ - $options = array(); - $options['alert-text'] = ! empty( $input['alert-text'] ) ? self::sanitize_space( esc_html( $input['alert-text'] ) ) : ''; - $options['alert-content'] = ! empty( $input['alert-content'] ) ? self::sanitize_space( stripslashes( htmlspecialchars( $input['alert-content'] ) ) ) : ''; - - foreach ( $post_types as $post_type ) { - $options['alert-display'][ $post_type['name'] ] = ! empty( $input['alert-display'][ $post_type['name'] ] ) ? 'display' : 'hide'; - } - $options['alert-hook'] = ! empty( $input['alert-hook'] ) ? self::sanitize_space( esc_html( $input['alert-hook'] ) ) : ''; - return $options; - } - - /** - * Render Setting Page - */ - public static function render_setting() { - - // 投稿タイプを取得 - $post_types = self::get_post_types(); - - // 許可されたHTMLタグ - $allowed_html = self::kses_allowed(); - - // オプションを取得 - $options = self::get_options(); - ?> -

-
+ } + + /** + * Sanitize Space + */ + public static function sanitize_space( $input ) { + if ( preg_match( '/^(\s)+$/u', $input ) ) { + return ''; + } + return $input; + } + + /** + * Sanitize Setting + */ + public static function sanitize_setting( $input ) { + + // 投稿タイプを取得 + $post_types = self::get_post_types(); + + // 許可されたHTMLタグ + $allowed_html = self::kses_allowed(); + + // サニタイズ処理 + $options = array(); + $options['alert-text'] = ! empty( $input['alert-text'] ) ? self::sanitize_space( esc_html( $input['alert-text'] ) ) : ''; + + // alert-contentを許可リストに基づいてサニタイズ + if ( ! empty( $input['alert-content'] ) ) { + $options['alert-content'] = wp_kses( stripslashes( $input['alert-content'] ), $allowed_html ); + } else { + $options['alert-content'] = ''; + } + + // 投稿タイプごとの設定をサニタイズ + $post_types = self::get_post_types(); + foreach ( $post_types as $post_type ) { + $options['alert-display'][ $post_type['name'] ] = ! empty( $input['alert-display'][ $post_type['name'] ] ) ? 'display' : 'hide'; + } + + $options['alert-hook'] = ! empty( $input['alert-hook'] ) ? self::sanitize_space( esc_html( $input['alert-hook'] ) ) : ''; + return $options; + } + + /** + * Render Setting Page + */ + public static function render_setting() { + + // 投稿タイプを取得 + $post_types = self::get_post_types(); + + // 許可されたHTMLタグ + $allowed_html = self::kses_allowed(); + + // オプションを取得 + $options = self::get_options(); + ?> +

+


- - - - + + + + + + + + +
+ + + + - - - - - - - - - -

- +

Ex)

    @@ -269,69 +278,69 @@ public static function render_setting() {
-
- -
    -
  • -
  • -
- -
-
    - -
  • - -
  • - -
-

-
-
- - - - - -
-



- -
- - - +
+ +
    +
  • +
  • +
+ +
+
    + +
  • + +
  • + +
+

+
+
+ + + + + +
+



+ +
+ +
+ '; - $alert_content .= $options['alert-content']; - $alert_content .= '
'; - } elseif ( ! empty( $options['alert-text'] ) ) { - $alert_content = '
'; - $alert_content .= ''; - $alert_content .= '' . $options['alert-text'] . ''; - $alert_content .= '
'; - } - - if ( ! empty( $alert_content ) ) { - $alert = '
' . $alert_content . '
'; - } - } - - return apply_filters( 'veu_promotion_alert_content', htmlspecialchars_decode( $alert ) ); - } - - /** - * Display Alert Content Filter Hook - */ - public static function display_alert_filter( $content ) { - - // アラートを取得 - $alert = self::get_alert_content(); - - // 文頭にアラートを追加 - $content = $alert . $content; - - return $content; - } - - /** - * Display Alert Content Action Hook - */ - public static function display_alert_action() { - - // アラートを取得 - $alert = self::get_alert_content(); - // 許可されたHTMLタグ - $allowed_html = self::kses_allowed(); - - echo wp_kses( $alert, $allowed_html ); - } - - /** - * Display Alert - */ - public static function display_alert() { - - // オプションを取得 - $options = self::get_options(); - if ( is_singular() ) { - if ( ! empty( $options['alert-hook'] ) ) { - add_action( $options['alert-hook'], array( __CLASS__, 'display_alert_action' ) ); - } else { - add_filter( 'the_content', array( __CLASS__, 'display_alert_filter' ) ); - } - } - } - - /** - * Inline Style - */ - public static function inline_style() { - - $dynamic_css = ' - .veu_promotion-alert__content--text { - border: 1px solid rgba(0,0,0,0.125); - padding: 0.5em 1em; - border-radius: var(--vk-size-radius); - margin-bottom: var(--vk-margin-block-bottom); - font-size: 0.875rem; - } - /* Alert Content部分に段落タグを入れた場合に最後の段落の余白を0にする */ - .veu_promotion-alert__content--text p:last-of-type{ - margin-bottom:0; - margin-top: 0; - } - '; - - // delete before after space - $dynamic_css = trim( $dynamic_css ); - // convert tab and br to space - $dynamic_css = preg_replace( '/[\n\r\t]/', '', $dynamic_css ); - // Change multiple spaces to single space - $dynamic_css = preg_replace( '/\s(?=\s)/', '', $dynamic_css ); - wp_add_inline_style( 'vkExUnit_common_style', $dynamic_css ); - } -} + } + + /** + * Display Condition + */ + public static function get_display_condition( $post_id ) { + + // 通常は false + $return = false; + + // カスタムフィールドを取得 + $meta = get_post_meta( $post_id, 'veu_display_promotion_alert', true ); + $meta = ! empty( $meta ) ? $meta : 'common'; + // オプションを取得 + $options = self::get_options(); + // 投稿タイプを取得 + $post_type = get_post_type( $post_id ); + // 表示条件を判定 + if ( 'display' === $meta ) { + // カスタムフィールドが display の場合は true + $return = true; + } elseif ( 'common' === $meta && ! empty( $options['alert-display'][ $post_type ] ) && 'display' === $options['alert-display'][ $post_type ] ) { + // カスタムフィールドが common でオプションが display の場合は true + $return = true; + } + + return $return; + } + + /** + * Alert Content + */ + public static function get_alert_content() { + // アラートを初期化 + $alert = ''; + $alert_content = ''; + + // 表示条件を判定 + $display = self::get_display_condition( get_the_ID() ); + + // 表示条件が true の場合はアラートを表示 + if ( ! empty( $display ) ) { + + // オプションを取得 + $options = self::get_options(); + + // 許可されたHTMLタグ + $allowed_html = self::kses_allowed(); + + // アラートの中身を作成 + if ( ! empty( $options['alert-content'] ) ) { + $alert_content = '
'; + $alert_content .= wp_kses( $options['alert-content'], $allowed_html ); + $alert_content .= '
'; + } elseif ( ! empty( $options['alert-text'] ) ) { + $alert_content = '
'; + $alert_content .= ''; + $alert_content .= '' . esc_html( $options['alert-text'] ) . ''; + $alert_content .= '
'; + } + + if ( ! empty( $alert_content ) ) { + // wp_ksesを通した後にdata-nosnippetを追加 + $alert = wp_kses( '
' . $alert_content . '
', $allowed_html ); + $alert = str_replace('
', '
', $alert); + } + } + + // 許可されたHTMLタグで再度サニタイズ + return apply_filters( 'veu_promotion_alert_content', $alert ); + } + + /** + * Display Alert Content Filter Hook + */ + public static function display_alert_filter( $content ) { + + // アラートを取得 + $alert = self::get_alert_content(); + + // 文頭にアラートを追加 + $content = $alert . $content; + + return $content; + } + + /** + * Display Alert Content Action Hook + */ + public static function display_alert_action() { + + // アラートを取得 + $alert = self::get_alert_content(); + // 許可されたHTMLタグ + $allowed_html = self::kses_allowed(); + + echo wp_kses( $alert, $allowed_html ); + } + + /** + * Display Alert + */ + public static function display_alert() { + + // オプションを取得 + $options = self::get_options(); + if ( is_singular() ) { + if ( ! empty( $options['alert-hook'] ) ) { + add_action( $options['alert-hook'], array( __CLASS__, 'display_alert_action' ) ); + } else { + add_filter( 'the_content', array( __CLASS__, 'display_alert_filter' ) ); + } + } + } + + /** + * Inline Style + */ + public static function inline_style() { + + $dynamic_css = ' + .veu_promotion-alert__content--text { + border: 1px solid rgba(0,0,0,0.125); + padding: 0.5em 1em; + border-radius: var(--vk-size-radius); + margin-bottom: var(--vk-margin-block-bottom); + font-size: 0.875rem; + } + /* Alert Content部分に段落タグを入れた場合に最後の段落の余白を0にする */ + .veu_promotion-alert__content--text p:last-of-type{ + margin-bottom:0; + margin-top: 0; + } + '; + + // delete before after space + $dynamic_css = trim( $dynamic_css ); + // convert tab and br to space + $dynamic_css = preg_replace( '/[\n\r\t]/', '', $dynamic_css ); + // Change multiple spaces to single space + $dynamic_css = preg_replace( '/\s(?=\s)/', '', $dynamic_css ); + wp_add_inline_style( 'vkExUnit_common_style', $dynamic_css ); + } +} diff --git a/readme.txt b/readme.txt index 9b0d14a1..278aad90 100644 --- a/readme.txt +++ b/readme.txt @@ -81,6 +81,8 @@ e.g. == Changelog == +[ Bug Fix ][ Promotion Alert ] Fixed filtering in Promotion Alert by adding data-nosnippet attribute to the div tag. + = 9.100.0 = [ Add setting ][ Category list ] Enable to specify ascending/descending order [ Specification Change ][ Twitter widget ] Added "Not recommended" to the name and added a note to the description. diff --git a/tests/test-promotion-alert.php b/tests/test-promotion-alert.php index b93b5630..06272f37 100644 --- a/tests/test-promotion-alert.php +++ b/tests/test-promotion-alert.php @@ -459,6 +459,42 @@ public function test_get_alert_content() { ), 'correct' => '', ), + // XSS属性の削除をテスト + array( + 'options' => array( + 'alert-content' => '
Hover me!
', + 'alert-display' => array('post' => 'display'), + ), + 'correct' => '
Hover me!
', + ), + array( + 'options' => array( + 'alert-content' => '', + 'alert-display' => array('post' => 'display'), + ), + 'correct' => '
', + ), + array( + 'options' => array( + 'alert-content' => '', + 'alert-display' => array('post' => 'display'), + ), + 'correct' => '
', + ), + array( + 'options' => array( + 'alert-content' => 'Click me!', + 'alert-display' => array('post' => 'display'), + ), + 'correct' => '', + ), + array( + 'options' => array( + 'alert-content' => '', + 'alert-display' => array('post' => 'display'), + ), + 'correct' => '
', + ), ); print PHP_EOL; @@ -491,4 +527,4 @@ public function test_get_alert_content() { } -} \ No newline at end of file +}