PluginProbe
Forumax – AI Powered Advanced Community Forum Plugin / trunk
Forumax – AI Powered Advanced Community Forum Plugin vtrunk
2.4.4 2.4.3 2.4.2 2.4.1 2.4.0 trunk 1.0.8 1.1.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 1.3.0 1.3.1 1.3.2 1.3.3 1.4.0 1.4.1 2.0.0 2.1.0 All 29 releases
bbp-core / includes / features / frmx-inline-edit.php

frmx-inline-edit.php in Forumax – AI Powered Advanced Community Forum Plugin trunk, at includes/features/frmx-inline-edit.php

255 lines 7.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Forumax Inline Edit Feature
4 *
5 * Provides AJAX-based inline editing for topics and replies
6 * so users can edit content without leaving the page.
7 *
8 * @package Forumax
9 */
10
11 defined( 'ABSPATH' ) || exit;
12
13 /**
14 * Class Forumax_Inline_Edit
15 *
16 * Handles inline editing for bbPress topics and replies.
17 */
18 class Forumax_Inline_Edit {
19
20 /**
21 * Constructor — register AJAX actions.
22 */
23 public function __construct() {
24 // Topic inline edit actions.
25 add_action( 'wp_ajax_forumax_get_topic_content', array( $this, 'get_topic_content' ) );
26 add_action( 'wp_ajax_forumax_save_topic_edit', array( $this, 'save_topic_edit' ) );
27
28 // Reply inline edit actions.
29 add_action( 'wp_ajax_forumax_get_reply_content', array( $this, 'get_reply_content' ) );
30 add_action( 'wp_ajax_forumax_save_reply_edit', array( $this, 'save_reply_edit' ) );
31 }
32
33 /**
34 * AJAX handler: Get raw topic content for editing.
35 *
36 * Returns the topic title and raw content for the inline editor.
37 */
38 public function get_topic_content() {
39 check_ajax_referer( 'forumax-nonce', 'nonce' );
40
41 $topic_id = isset( $_POST['topic_id'] ) ? absint( $_POST['topic_id'] ) : 0;
42
43 if ( ! $topic_id ) {
44 wp_send_json_error( array( 'message' => esc_html__( 'Invalid topic ID.', 'forumax' ) ) );
45 }
46
47 // Verify the user can edit this topic.
48 if ( ! current_user_can( 'edit_post', $topic_id ) ) {
49 wp_send_json_error( array( 'message' => esc_html__( 'You do not have permission to edit this topic.', 'forumax' ) ) );
50 }
51
52 $topic = get_post( $topic_id );
53
54 if ( ! $topic || bbp_get_topic_post_type() !== $topic->post_type ) {
55 wp_send_json_error( array( 'message' => esc_html__( 'Topic not found.', 'forumax' ) ) );
56 }
57
58 wp_send_json_success( array(
59 'title' => $topic->post_title,
60 'content' => $topic->post_content,
61 ) );
62 }
63
64 /**
65 * AJAX handler: Save inline-edited topic.
66 *
67 * Updates the topic title and content via AJAX.
68 */
69 public function save_topic_edit() {
70 check_ajax_referer( 'forumax-nonce', 'nonce' );
71
72 $topic_id = isset( $_POST['topic_id'] ) ? absint( $_POST['topic_id'] ) : 0;
73
74 if ( ! $topic_id ) {
75 wp_send_json_error( array( 'message' => esc_html__( 'Invalid topic ID.', 'forumax' ) ) );
76 }
77
78 // Verify the user can edit this topic.
79 if ( ! current_user_can( 'edit_post', $topic_id ) ) {
80 wp_send_json_error( array( 'message' => esc_html__( 'You do not have permission to edit this topic.', 'forumax' ) ) );
81 }
82
83 $topic = get_post( $topic_id );
84
85 if ( ! $topic || bbp_get_topic_post_type() !== $topic->post_type ) {
86 wp_send_json_error( array( 'message' => esc_html__( 'Topic not found.', 'forumax' ) ) );
87 }
88
89 // Sanitize inputs.
90 $new_title = isset( $_POST['title'] ) ? sanitize_text_field( wp_unslash( $_POST['title'] ) ) : '';
91 $new_content = isset( $_POST['content'] ) ? wp_kses_post( wp_unslash( $_POST['content'] ) ) : '';
92
93 if ( empty( $new_title ) ) {
94 wp_send_json_error( array( 'message' => esc_html__( 'Title cannot be empty.', 'forumax' ) ) );
95 }
96
97 if ( empty( $new_content ) ) {
98 wp_send_json_error( array( 'message' => esc_html__( 'Content cannot be empty.', 'forumax' ) ) );
99 }
100
101 // Update the topic.
102 $updated = wp_update_post( array(
103 'ID' => $topic_id,
104 'post_title' => $new_title,
105 'post_content' => $new_content,
106 ), true );
107
108 if ( is_wp_error( $updated ) ) {
109 wp_send_json_error( array( 'message' => $updated->get_error_message() ) );
110 }
111
112 // Log the revision (bbPress tracks edits).
113 $revision_id = wp_save_post_revision( $topic_id );
114 if ( $revision_id ) {
115 bbp_update_topic_revision_log( array(
116 'topic_id' => $topic_id,
117 'revision_id' => $revision_id,
118 'author_id' => bbp_get_current_user_id(),
119 'reason' => esc_html__( 'Inline edit', 'forumax' ),
120 ) );
121 }
122
123 // Return the rendered content for display.
124 $updated_topic = get_post( $topic_id );
125
126 wp_send_json_success( array(
127 'title' => esc_html( $updated_topic->post_title ),
128 'content' => apply_filters( 'bbp_get_topic_content', $updated_topic->post_content, $topic_id ),
129 'message' => esc_html__( 'Topic updated successfully.', 'forumax' ),
130 ) );
131 }
132
133 /**
134 * AJAX handler: Get raw reply content for editing.
135 *
136 * Returns the reply raw content for the inline editor.
137 */
138 public function get_reply_content() {
139 check_ajax_referer( 'forumax-nonce', 'nonce' );
140
141 $reply_id = isset( $_POST['reply_id'] ) ? absint( $_POST['reply_id'] ) : 0;
142
143 if ( ! $reply_id ) {
144 wp_send_json_error( array( 'message' => esc_html__( 'Invalid reply ID.', 'forumax' ) ) );
145 }
146
147 // Verify the user can edit this reply.
148 if ( ! current_user_can( 'edit_post', $reply_id ) ) {
149 wp_send_json_error( array( 'message' => esc_html__( 'You do not have permission to edit this reply.', 'forumax' ) ) );
150 }
151
152 $reply = get_post( $reply_id );
153
154 if ( ! $reply || bbp_get_reply_post_type() !== $reply->post_type ) {
155 wp_send_json_error( array( 'message' => esc_html__( 'Reply not found.', 'forumax' ) ) );
156 }
157
158 wp_send_json_success( array(
159 'content' => $reply->post_content,
160 ) );
161 }
162
163 /**
164 * AJAX handler: Save inline-edited reply.
165 *
166 * Updates the reply content via AJAX.
167 */
168 public function save_reply_edit() {
169 check_ajax_referer( 'forumax-nonce', 'nonce' );
170
171 $reply_id = isset( $_POST['reply_id'] ) ? absint( $_POST['reply_id'] ) : 0;
172
173 if ( ! $reply_id ) {
174 wp_send_json_error( array( 'message' => esc_html__( 'Invalid reply ID.', 'forumax' ) ) );
175 }
176
177 // Verify the user can edit this reply.
178 if ( ! current_user_can( 'edit_post', $reply_id ) ) {
179 wp_send_json_error( array( 'message' => esc_html__( 'You do not have permission to edit this reply.', 'forumax' ) ) );
180 }
181
182 $reply = get_post( $reply_id );
183
184 if ( ! $reply || bbp_get_reply_post_type() !== $reply->post_type ) {
185 wp_send_json_error( array( 'message' => esc_html__( 'Reply not found.', 'forumax' ) ) );
186 }
187
188 // Sanitize input.
189 $new_content = isset( $_POST['content'] ) ? wp_kses_post( wp_unslash( $_POST['content'] ) ) : '';
190
191 if ( empty( $new_content ) ) {
192 wp_send_json_error( array( 'message' => esc_html__( 'Content cannot be empty.', 'forumax' ) ) );
193 }
194
195 // Update the reply.
196 $updated = wp_update_post( array(
197 'ID' => $reply_id,
198 'post_content' => $new_content,
199 ), true );
200
201 if ( is_wp_error( $updated ) ) {
202 wp_send_json_error( array( 'message' => $updated->get_error_message() ) );
203 }
204
205 // Log the revision (bbPress tracks edits).
206 $revision_id = wp_save_post_revision( $reply_id );
207 if ( $revision_id ) {
208 bbp_update_reply_revision_log( array(
209 'reply_id' => $reply_id,
210 'revision_id' => $revision_id,
211 'author_id' => bbp_get_current_user_id(),
212 'reason' => esc_html__( 'Inline edit', 'forumax' ),
213 ) );
214 }
215
216 // Return the rendered content for display.
217 $updated_reply = get_post( $reply_id );
218
219 // Set up global post data so action hooks can access the correct reply.
220 global $post;
221 $original_post = $post;
222 $post = $updated_reply;
223 setup_postdata( $post );
224
225 // Capture the full rendered content including action hooks.
226 ob_start();
227
228 // Trigger before content action (includes "Replying to" label).
229 do_action( 'bbp_theme_before_reply_content' );
230
231 // Output the reply content using bbPress function.
232 bbp_reply_content( $reply_id );
233
234 // Trigger after content action (includes nested reply button).
235 do_action( 'bbp_theme_after_reply_content' );
236
237 $rendered_content = ob_get_clean();
238
239 // Restore original post data.
240 $post = $original_post;
241 if ( $original_post ) {
242 setup_postdata( $original_post );
243 }
244 wp_reset_postdata();
245
246 wp_send_json_success( array(
247 'content' => $rendered_content,
248 'message' => esc_html__( 'Reply updated successfully.', 'forumax' ),
249 ) );
250 }
251 }
252
253 // Initialize the inline edit feature.
254 new Forumax_Inline_Edit();
255