| 1 | <?php |
| 2 | |
| 3 | namespace WordPressdotorg\Forums; |
| 4 | |
| 5 | class User_Notes { |
| 6 | /** |
| 7 | * An array of authors who have written notes. |
| 8 | * |
| 9 | * These are stored to avoid looking up user IDs for every note. |
| 10 | * |
| 11 | * @access private |
| 12 | * |
| 13 | * @var array $note_authors |
| 14 | */ |
| 15 | private $note_authors = array(); |
| 16 | |
| 17 | /** |
| 18 | * An array of all notes for each user. |
| 19 | * |
| 20 | * As users may have written multiple replies, in a thread, this will save us needing to look up all notes multiple times. |
| 21 | * |
| 22 | * @access private |
| 23 | * |
| 24 | * @var array $user_notes |
| 25 | */ |
| 26 | private $user_notes = array(); |
| 27 | |
| 28 | public function __construct() { |
| 29 | add_action( 'bbp_theme_after_reply_author_details', array( $this, 'user_note_link' ) ); |
| 30 | add_action( 'bbp_theme_after_reply_content', array( $this, 'user_note_fields' ) ); |
| 31 | |
| 32 | add_action( 'bbp_template_after_user_profile', array( $this, 'user_profile_notes_section' ) ); |
| 33 | |
| 34 | add_action( 'init', array( $this, 'add_note' ) ); |
| 35 | |
| 36 | add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) ); |
| 37 | } |
| 38 | |
| 39 | /** |
| 40 | * Append a notes section to user profiles |
| 41 | * |
| 42 | * @return void |
| 43 | */ |
| 44 | function user_profile_notes_section() { |
| 45 | if ( ! current_user_can( 'moderate' ) ) { |
| 46 | return; |
| 47 | } |
| 48 | $user = bbp_get_user_id(); |
| 49 | |
| 50 | printf( |
| 51 | '<h2 class="entry-title">%s</h2>', |
| 52 | esc_html__( 'User Notes', 'wporg-forums' ) |
| 53 | ); |
| 54 | |
| 55 | $this->output_user_notes( $user ); |
| 56 | } |
| 57 | |
| 58 | /** |
| 59 | * Check if a note is added to a post and add it to the relevant users meta data |
| 60 | * |
| 61 | * @return void |
| 62 | */ |
| 63 | function add_note() { |
| 64 | // Make sure a note is added, and that the current user has capabilities to add them |
| 65 | if ( ! isset( $_POST['bbp-user-notes-new-note'] ) || empty( $_POST['bbp-user-notes-new-note'] ) || ! current_user_can( 'moderate' ) ) { |
| 66 | return; |
| 67 | } |
| 68 | |
| 69 | // Make sure our nonces are in order |
| 70 | if ( ! check_admin_referer( sprintf( 'bbp_user_note-add-%d', $_POST['bbp-user-note-user-id'] ), '_bbp_user_note_nonce' ) ) { |
| 71 | wp_die(); |
| 72 | } |
| 73 | |
| 74 | // Ensure the ID used is an integer, and a legitimate user |
| 75 | $check_user = get_user_by( 'ID', intval( $_POST['bbp-user-note-user-id'] ) ); |
| 76 | if ( ! $check_user ) { |
| 77 | return; |
| 78 | } |
| 79 | |
| 80 | // Get an array of existing notes, or create an array if there are none |
| 81 | $user_notes = get_user_meta( $check_user->ID, '_bbp_user_note', true ); |
| 82 | if ( ! $user_notes ) { |
| 83 | $user_notes = array(); |
| 84 | } |
| 85 | |
| 86 | // Add the new note to the array of notes |
| 87 | $user_notes[] = (object) array( |
| 88 | 'note' => wp_kses( $_POST['bbp-user-notes-new-note'], array( 'a' => array( 'href' => array() ) ) ), |
| 89 | 'time' => date( "c" ), |
| 90 | 'post' => bbp_get_reply_url( intval( $_POST['bbp-user-note-original-reply'] ) ), |
| 91 | 'author' => get_current_user_id() |
| 92 | ); |
| 93 | |
| 94 | update_user_meta( $check_user->ID, '_bbp_user_note', $user_notes ); |
| 95 | } |
| 96 | |
| 97 | /** |
| 98 | * Register scripts and styles that plugin relies on. |
| 99 | * |
| 100 | * @return void |
| 101 | */ |
| 102 | function enqueue_scripts() { |
| 103 | if ( ! current_user_can( 'moderate' ) ) { |
| 104 | return; |
| 105 | } |
| 106 | |
| 107 | wp_enqueue_script( 'bbpress-user-notes', plugins_url( '/js/user-notes.js', __DIR__ ), array( 'jquery' ), false, true ); |
| 108 | } |
| 109 | |
| 110 | /** |
| 111 | * Add the toggle link for notes to the author area of a post |
| 112 | * |
| 113 | * @return void |
| 114 | */ |
| 115 | function user_note_link() { |
| 116 | if ( ! current_user_can( 'moderate' ) ) { |
| 117 | return; |
| 118 | } |
| 119 | |
| 120 | printf( |
| 121 | '<span class="bbpress-user-notes-toggle" data-bbp-user-note-toggle="#bbpress-user-notes-%d">%s</span>', |
| 122 | esc_attr( get_the_ID() ), |
| 123 | esc_html( |
| 124 | sprintf( |
| 125 | __( 'Toggle user notes (%d)', 'wporg-forums' ), |
| 126 | $this->user_note_count() |
| 127 | ) |
| 128 | ) |
| 129 | ); |
| 130 | |
| 131 | } |
| 132 | |
| 133 | /** |
| 134 | * @param int $user Default null. The user to get counts for, the default being the current user. |
| 135 | * |
| 136 | * @return int |
| 137 | */ |
| 138 | function user_note_count( $user = null ) { |
| 139 | if ( empty( $user ) ) { |
| 140 | $user = get_the_author_meta( 'ID' ); |
| 141 | } |
| 142 | |
| 143 | if ( ! isset( $this->user_notes[ $user ] ) ) { |
| 144 | $this->set_user_note_fields( $user ); |
| 145 | } |
| 146 | |
| 147 | return $this->user_notes[ $user ]['count']; |
| 148 | } |
| 149 | |
| 150 | function set_user_note_fields( $user = null ) { |
| 151 | if ( empty( $user ) ) { |
| 152 | $user = get_the_author_meta( 'ID' ); |
| 153 | } |
| 154 | |
| 155 | // Break out early if the notes are already grabbed for this session |
| 156 | if ( isset( $this->user_notes[ $user ] ) ) { |
| 157 | return; |
| 158 | } |
| 159 | |
| 160 | $user_notes = get_user_meta( $user, '_bbp_user_note', true ); |
| 161 | |
| 162 | $this->user_notes[ $user ] = array( |
| 163 | 'count' => 0, |
| 164 | 'raw' => null, |
| 165 | 'html' => array() |
| 166 | ); |
| 167 | |
| 168 | if ( is_array( $user_notes ) ) { |
| 169 | $this->user_notes[ $user ]['count'] = count( $user_notes ); |
| 170 | $this->user_notes[ $user ]['raw'] = $user_notes; |
| 171 | |
| 172 | foreach ( $user_notes AS $user_note ) { |
| 173 | if ( ! isset( $this->note_authors[ $user_note->author ] ) ) { |
| 174 | $this->note_authors[ $user_note->author ] = get_user_by( 'ID', $user_note->author ); |
| 175 | } |
| 176 | |
| 177 | $this->user_notes[ $user ]['html'][] = sprintf( |
| 178 | '<div class="bbpress-user-note-single">%s <span class="bbpress-user-note-meta">%s</span></div>', |
| 179 | wp_kses( $user_note->note, array( 'a' => array( 'href' => array() ) ) ), |
| 180 | sprintf( |
| 181 | /* translators: 1: Users display name 2: Link to post 3: Time of creation */ |
| 182 | __( 'by %1$s at <a href="%2$s">%3$s</a>', 'wporg-forums' ), |
| 183 | esc_html( $this->note_authors[ $user_note->author ]->display_name ), |
| 184 | esc_url( $user_note->post ), |
| 185 | date_i18n( "Y-m-d H:i:s", strtotime( $user_note->time ) ) |
| 186 | ) |
| 187 | ); |
| 188 | } |
| 189 | } |
| 190 | } |
| 191 | |
| 192 | /** |
| 193 | * @param $user |
| 194 | * |
| 195 | * @return void |
| 196 | */ |
| 197 | function output_user_notes( $user ) { |
| 198 | if ( ! isset( $this->user_notes[ $user ] ) ) { |
| 199 | $this->set_user_note_fields( $user ); |
| 200 | } |
| 201 | |
| 202 | if ( ! empty( $this->user_notes[ $user ]['html'] ) ) { |
| 203 | echo implode( '', $this->user_notes[ $user ]['html'] ); |
| 204 | } else { |
| 205 | esc_html_e( |
| 206 | 'No notes have been added to this user.', |
| 207 | 'wporg-forums' |
| 208 | ); |
| 209 | } |
| 210 | } |
| 211 | |
| 212 | /** |
| 213 | * Output all existing users notes, and the form for adding new ones to a hidden area in the post content. |
| 214 | * |
| 215 | * @return void |
| 216 | */ |
| 217 | function user_note_fields() { |
| 218 | if ( ! current_user_can( 'moderate' ) ) { |
| 219 | return; |
| 220 | } |
| 221 | |
| 222 | $lookup_user = get_the_author_meta( 'ID' ); |
| 223 | |
| 224 | $this->set_user_note_fields( $lookup_user ); |
| 225 | |
| 226 | printf( |
| 227 | '<div class="bbpress-user-notes" id="bbpress-user-notes-%d">', |
| 228 | esc_attr( get_the_ID() ) |
| 229 | ); |
| 230 | |
| 231 | printf( |
| 232 | '<h2>%s</h2>', |
| 233 | esc_html__( 'User notes', 'wporg-forums' ) |
| 234 | ); |
| 235 | |
| 236 | $this->output_user_notes( $lookup_user ); |
| 237 | |
| 238 | $this->add_note_form(); |
| 239 | |
| 240 | echo '</div>'; |
| 241 | } |
| 242 | |
| 243 | /** |
| 244 | * Generate the form for adding new notes |
| 245 | * |
| 246 | * @return void |
| 247 | */ |
| 248 | function add_note_form() { |
| 249 | ?> |
| 250 | <form action="<?php echo esc_url( sprintf( '%s#post-%d', bbp_get_topic_permalink(), get_the_ID() ) ); ?>" method="post" class="bbp-add-user-note"> |
| 251 | <input type="hidden" name="bbp-user-note-user-id" value="<?php echo esc_attr( get_the_author_meta( 'ID' ) ); ?>"> |
| 252 | <input type="hidden" name="action" value="bbpress-user-notes-add"> |
| 253 | <input type="hidden" name="bbp-user-note-original-reply" value="<?php echo esc_attr( get_the_ID() ); ?>"> |
| 254 | |
| 255 | <?php wp_nonce_field( sprintf( 'bbp_user_note-add-%d', get_the_author_meta( 'ID' ) ), '_bbp_user_note_nonce' ); ?> |
| 256 | |
| 257 | <label for="bbp-user-notes-new-note" class="screen-reader-text"><?php esc_html_e( 'New note:', 'wporg-forums' ); ?></label> |
| 258 | <textarea name="bbp-user-notes-new-note" id="bbp-user-notes-new-note"></textarea> |
| 259 | |
| 260 | <button type="submit"><?php esc_html_e( 'Add your note', 'wporg-forums' ); ?></button> |
| 261 | </form> |
| 262 | <?php |
| 263 | } |
| 264 | } |
| 265 | No newline at end of file |