| 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 | } |