| | 1 | <?php |
| | 2 | |
| | 3 | namespace WordPressdotorg\Forums; |
| | 4 | |
| | 5 | class NSFW_Handler { |
| | 6 | |
| | 7 | public function __construct() { |
| | 8 | add_action( 'init', array( $this, 'register_taxonomy' ) ); |
| | 9 | |
| | 10 | add_action( 'bbp_new_topic_post_extras', array( $this, 'manually_assign_nsfw_flag' ), 10 ); |
| | 11 | add_action( 'bbp_edit_topic_post_extras', array( $this, 'manually_assign_nsfw_flag' ), 10 ); |
| | 12 | |
| | 13 | add_action( 'bbp_new_topic_post_extras', array( $this, 'maybe_flag_nsfw_automatically' ), 11 ); |
| | 14 | add_action( 'bbp_edit_topic_post_extras', array( $this, 'maybe_flag_nsfw_automatically' ), 11 ); |
| | 15 | |
| | 16 | add_action( 'nsfw_terms_add_form_fields', array( $this, 'add_term_meta' ) ); |
| | 17 | |
| | 18 | add_action( 'bbp_theme_before_topic_form_subscriptions', array( $this, 'mark_topic_nsfw_form_field' ) ); |
| | 19 | |
| | 20 | add_filter( 'bbp_get_topic_title', array( $this, 'prepend_topic_title' ), 10, 2 ); |
| | 21 | |
| | 22 | add_action( 'admin_head', array( $this, 'taxonomy_styles' ) ); |
| | 23 | } |
| | 24 | |
| | 25 | /** |
| | 26 | * Provide additional term meta fields. |
| | 27 | */ |
| | 28 | public function add_term_meta() { |
| | 29 | // Output a helping text indicating what to use the description field for. |
| | 30 | echo '<p>' . __( 'Please provide a reason for adding this term in the description field', 'wporg-forums' ) . '</p>'; |
| | 31 | } |
| | 32 | |
| | 33 | /** |
| | 34 | * Output some CSS to keep the NSFW term interface as simple as possible. |
| | 35 | */ |
| | 36 | public function taxonomy_styles() { |
| | 37 | if ( ! isset( $_GET['taxonomy'] ) || 'nsfw_terms' !== $_GET['taxonomy'] ) { |
| | 38 | return; |
| | 39 | } |
| | 40 | |
| | 41 | ?> |
| | 42 | |
| | 43 | <style type="text/css"> |
| | 44 | body.taxonomy-nsfw_terms .term-slug-wrap { |
| | 45 | display: none; |
| | 46 | } |
| | 47 | body.taxonomy-nsfw_terms .column-posts, |
| | 48 | body.taxonomy-nsfw_terms .column-slug { |
| | 49 | display: none; |
| | 50 | } |
| | 51 | </style> |
| | 52 | |
| | 53 | <?php |
| | 54 | } |
| | 55 | |
| | 56 | public function register_taxonomy() { |
| | 57 | register_taxonomy( |
| | 58 | 'nsfw_terms', |
| | 59 | 'forum', |
| | 60 | array( |
| | 61 | 'labels' => array( |
| | 62 | 'name' => __( 'NSFW Terms', 'wporg-forums' ), |
| | 63 | ), |
| | 64 | 'description' => __( 'Declare terms for mature content that the forums will automatically mark not safe for work (NSFW)', 'wporg-forums' ), |
| | 65 | 'public' => false, |
| | 66 | 'show_ui' => true, |
| | 67 | 'show_in_menu' => true, |
| | 68 | 'show_in_rest' => false, |
| | 69 | 'show_tagcloud' => false, |
| | 70 | 'show_in_quick_edit' => false, |
| | 71 | 'capabilities' => array( |
| | 72 | 'keep_gate', |
| | 73 | ), |
| | 74 | ) |
| | 75 | ); |
| | 76 | } |
| | 77 | |
| | 78 | /** |
| | 79 | * Helper to check if a topic is in a forum that should get the added features of this file. |
| | 80 | * |
| | 81 | * @param $topic_id |
| | 82 | * |
| | 83 | * @return bool |
| | 84 | */ |
| | 85 | private function topic_in_affected_forum( $topic_id ) { |
| | 86 | return ( Plugin::REVIEWS_FORUM_ID != bbp_get_topic_forum_id( $topic_id ) && ( ! bbp_is_single_view() || 'reviews' !== bbp_get_view_id() ) ); |
| | 87 | } |
| | 88 | |
| | 89 | /** |
| | 90 | * Output an additional form field when creating or editing a topic to mark it as containing mature content. |
| | 91 | */ |
| | 92 | public function mark_topic_nsfw_form_field() { |
| | 93 | $topic_id = bbp_get_topic_id(); |
| | 94 | |
| | 95 | if ( $this->topic_in_affected_forum( $topic_id ) ) { |
| | 96 | $checked = false; |
| | 97 | |
| | 98 | if ( bbp_is_topic_edit() ) { |
| | 99 | $checked = get_post_meta( $topic_id, '_topic_is_nsfw', true ); |
| | 100 | } |
| | 101 | |
| | 102 | ?> |
| | 103 | |
| | 104 | <p> |
| | 105 | <label for="topic-is-nsfw"> |
| | 106 | <input type="checkbox" name="topic_is_nsfw" id="topic-is-nsfw" <?php checked( true, $checked ); ?>> |
| | 107 | <?php esc_html_e( 'This topic relates to mature content and may be considered Not Safe For Work (NSFW)', 'wporg-forums' ); ?> |
| | 108 | </label> |
| | 109 | </p> |
| | 110 | |
| | 111 | <?php |
| | 112 | } |
| | 113 | } |
| | 114 | |
| | 115 | /** |
| | 116 | * Capture manually assigned mature content from form submissions. |
| | 117 | * |
| | 118 | * @param $topic_id |
| | 119 | */ |
| | 120 | public function manually_assign_nsfw_flag( $topic_id ) { |
| | 121 | if ( ! $this->topic_in_affected_forum( $topic_id ) ) { |
| | 122 | return; |
| | 123 | } |
| | 124 | |
| | 125 | if ( isset( $_POST['topic_is_nsfw'] ) ) { |
| | 126 | update_post_meta( $topic_id, '_topic_is_nsfw', true ); |
| | 127 | } else { |
| | 128 | update_post_meta( $topic_id, '_topic_is_nsfw', false ); |
| | 129 | } |
| | 130 | } |
| | 131 | |
| | 132 | /** |
| | 133 | * Automatically test if a topic might contain mature content when being published. |
| | 134 | * |
| | 135 | * @param $topic_id |
| | 136 | */ |
| | 137 | public function maybe_flag_nsfw_automatically( $topic_id ) { |
| | 138 | // If the topic was manually flagged, save some processing by not seeing if it needs automatic flagging. |
| | 139 | if ( isset( $_POST['topic_is_nsfw'] ) ) { |
| | 140 | return; |
| | 141 | } |
| | 142 | |
| | 143 | /* Skip checking for moderators, this is so that the flagging happens even on edits |
| | 144 | * by users, but allows mods to force-remove the tag if needed. |
| | 145 | */ |
| | 146 | if ( current_user_can( 'moderate' ) ) { |
| | 147 | return; |
| | 148 | } |
| | 149 | |
| | 150 | $topic_title = bbp_get_topic_title( $topic_id ); |
| | 151 | $topic_url = ( isset( $_POST['site_url'] ) && ! empty( $_POST['site_url'] ) ? $_POST['site_url'] : null ); |
| | 152 | |
| | 153 | $terms = get_terms( |
| | 154 | array( |
| | 155 | 'taxonomy' => 'nsfw_terms', |
| | 156 | 'hide_empty' => false, |
| | 157 | ) |
| | 158 | ); |
| | 159 | |
| | 160 | foreach ( $terms as $term ) { |
| | 161 | // If the term is found in the title or URL field, mark it as NSFW and stop processing. |
| | 162 | if ( stristr( $topic_title, $term->name ) || ( null !== $topic_url && stristr( $topic_url, $term->name ) ) ) { |
| | 163 | update_post_meta( $topic_id, '_topic_is_nsfw', true ); |
| | 164 | return; |
| | 165 | } |
| | 166 | } |
| | 167 | } |
| | 168 | |
| | 169 | /** |
| | 170 | * Add a NSFW tag to any title marked as such. |
| | 171 | * |
| | 172 | * @param $title |
| | 173 | * @param $topic_id |
| | 174 | * |
| | 175 | * @return string |
| | 176 | */ |
| | 177 | public function prepend_topic_title( $title, $topic_id ) { |
| | 178 | $is_nsfw = get_post_meta( $topic_id, '_topic_is_nsfw', true ); |
| | 179 | |
| | 180 | if ( ! $is_nsfw ) { |
| | 181 | return $title; |
| | 182 | } |
| | 183 | |
| | 184 | $prefix = sprintf( |
| | 185 | '<abbr title="%s">%s</abbr>', |
| | 186 | // translators: Explanation of what the abbreviation NSFW means. |
| | 187 | esc_attr( __( 'Not Safe For Work / Mature content', 'wporg-forums' ) ), |
| | 188 | // translators: Prepended titles for topics with mature content. |
| | 189 | __( '[NSFW]', 'wporg-forums' ) |
| | 190 | ); |
| | 191 | |
| | 192 | return sprintf( |
| | 193 | '%s %s', |
| | 194 | $prefix, |
| | 195 | $title |
| | 196 | ); |
| | 197 | } |
| | 198 | |
| | 199 | } |