PluginProbe
bbPress / 2.6.6
bbPress v2.6.6
trunk 2.0 2.0-beta-1 2.0-beta-2b 2.0-beta-3 2.0-beta-3b 2.0-rc-2 2.0-rc-3 2.0-rc-4 2.0-rc-5 2.0.1 2.0.2 2.0.3 2.1 2.1-beta-1 2.1-rc1 2.1-rc2 2.1-rc3 2.1-rc4 2.1.1 2.1.2 2.1.3 2.2 2.2.1 2.2.2 All 71 releases
← All changes | includes/common/classes.php +264 -142 2.22.6.6 View file →
@@ -7,11 +7,11 @@
7 7 * @subpackage Classes
8 8 */
9 9
10 10 // Exit if accessed directly
11 -if ( !defined( 'ABSPATH' ) ) exit;
11 +defined( 'ABSPATH' ) || exit;
12 12
13 -if ( !class_exists( 'BBP_Component' ) ) :
13 +if ( ! class_exists( 'BBP_Component' ) ) :
14 14 /**
15 15 * bbPress Component Class
16 16 *
17 17 * The bbPress component class is responsible for simplifying the creation
@@ -21,9 +21,9 @@
21 21 *
22 22 * @package bbPress
23 23 * @subpackage Classes
24 24 *
25 - * @since bbPress (r2688)
25 + * @since 2.0.0 bbPress (r2688)
26 26 */
27 27 class BBP_Component {
28 28
29 29 /**
@@ -57,23 +57,21 @@
57 57
58 58 /**
59 59 * bbPress Component loader
60 60 *
61 - * @since bbPress (r2700)
61 + * @since 2.0.0 bbPress (r2700)
62 62 *
63 - * @param mixed $args Required. Supports these args:
63 + * @param array $args Required. Supports these args:
64 64 * - name: Unique name (for internal identification)
65 65 * - id: Unique ID (normally for custom post type)
66 66 * - slug: Unique slug (used in query string and permalinks)
67 67 * - query: The loop for this component (WP_Query)
68 68 * - current_id: The current ID of the queried object
69 - * @uses BBP_Component::setup_globals() Setup the globals needed
70 - * @uses BBP_Component::includes() Include the required files
71 - * @uses BBP_Component::setup_actions() Setup the hooks and actions
72 69 */
73 - public function __construct( $args = '' ) {
74 - if ( empty( $args ) )
70 + public function __construct( $args = array() ) {
71 + if ( empty( $args ) ) {
75 72 return;
73 + }
76 74
77 75 $this->setup_globals( $args );
78 76 $this->includes();
79 77 $this->setup_actions();
@@ -81,15 +79,13 @@
81 79
82 80 /**
83 81 * Component global variables
84 82 *
85 - * @since bbPress (r2700)
83 + * @since 2.0.0 bbPress (r2700)
84 + *
86 85 * @access private
87 - *
88 - * @uses apply_filters() Calls 'bbp_{@link BBP_Component::name}_id'
89 - * @uses apply_filters() Calls 'bbp_{@link BBP_Component::name}_slug'
90 86 */
91 - private function setup_globals( $args = '' ) {
87 + private function setup_globals( $args = array() ) {
92 88 $this->name = $args['name'];
93 89 $this->id = apply_filters( 'bbp_' . $this->name . '_id', $args['id'] );
94 90 $this->slug = apply_filters( 'bbp_' . $this->name . '_slug', $args['slug'] );
95 91 }
@@ -96,12 +92,11 @@
96 92
97 93 /**
98 94 * Include required files
99 95 *
100 - * @since bbPress (r2700)
96 + * @since 2.0.0 bbPress (r2700)
97 + *
101 98 * @access private
102 - *
103 - * @uses do_action() Calls 'bbp_{@link BBP_Component::name}includes'
104 99 */
105 100 private function includes() {
106 101 do_action( 'bbp_' . $this->name . 'includes' );
107 102 }
@@ -108,14 +103,11 @@
108 103
109 104 /**
110 105 * Setup the actions
111 106 *
112 - * @since bbPress (r2700)
107 + * @since 2.0.0 bbPress (r2700)
108 + *
113 109 * @access private
114 - *
115 - * @uses add_action() To add various actions
116 - * @uses do_action() Calls
117 - * 'bbp_{@link BBP_Component::name}setup_actions'
118 110 */
119 111 private function setup_actions() {
120 112 add_action( 'bbp_register_post_types', array( $this, 'register_post_types' ), 10, 2 ); // Register post types
121 113 add_action( 'bbp_register_taxonomies', array( $this, 'register_taxonomies' ), 10, 2 ); // Register taxonomies
@@ -128,11 +120,9 @@
128 120
129 121 /**
130 122 * Setup the component post types
131 123 *
132 - * @since bbPress (r2700)
133 - *
134 - * @uses do_action() Calls 'bbp_{@link BBP_Component::name}_register_post_types'
124 + * @since 2.0.0 bbPress (r2700)
135 125 */
136 126 public function register_post_types() {
137 127 do_action( 'bbp_' . $this->name . '_register_post_types' );
138 128 }
@@ -139,11 +129,9 @@
139 129
140 130 /**
141 131 * Register component specific taxonomies
142 132 *
143 - * @since bbPress (r2700)
144 - *
145 - * @uses do_action() Calls 'bbp_{@link BBP_Component::name}_register_taxonomies'
133 + * @since 2.0.0 bbPress (r2700)
146 134 */
147 135 public function register_taxonomies() {
148 136 do_action( 'bbp_' . $this->name . '_register_taxonomies' );
149 137 }
@@ -150,11 +138,9 @@
150 138
151 139 /**
152 140 * Add any additional rewrite tags
153 141 *
154 - * @since bbPress (r2700)
155 - *
156 - * @uses do_action() Calls 'bbp_{@link BBP_Component::name}_add_rewrite_tags'
142 + * @since 2.0.0 bbPress (r2700)
157 143 */
158 144 public function add_rewrite_tags() {
159 145 do_action( 'bbp_' . $this->name . '_add_rewrite_tags' );
160 146 }
@@ -161,11 +147,9 @@
161 147
162 148 /**
163 149 * Generate any additional rewrite rules
164 150 *
165 - * @since bbPress (r2700)
166 - *
167 - * @uses do_action() Calls 'bbp_{@link BBP_Component::name}_generate_rewrite_rules'
151 + * @since 2.0.0 bbPress (r2700)
168 152 */
169 153 public function generate_rewrite_rules( $wp_rewrite ) {
170 154 do_action_ref_array( 'bbp_' . $this->name . '_generate_rewrite_rules', $wp_rewrite );
171 155 }
@@ -173,36 +157,37 @@
173 157 endif; // BBP_Component
174 158
175 159 if ( class_exists( 'Walker' ) ) :
176 160 /**
177 - * Create HTML list of forums.
161 + * Create HTML dropdown list of bbPress forums/topics.
178 162 *
179 163 * @package bbPress
180 164 * @subpackage Classes
181 165 *
182 - * @since bbPress (r2514)
183 - *
184 - * @uses Walker
166 + * @since 2.0.0 bbPress (r2746)
185 167 */
186 -class BBP_Walker_Forum extends Walker {
168 +class BBP_Walker_Dropdown extends Walker {
187 169
188 170 /**
189 171 * @see Walker::$tree_type
190 172 *
191 - * @since bbPress (r2514)
173 + * @since 2.0.0 bbPress (r2746)
192 174 *
193 175 * @var string
194 176 */
195 - var $tree_type;
177 + public $tree_type = 'forum';
196 178
197 179 /**
198 180 * @see Walker::$db_fields
199 181 *
200 - * @since bbPress (r2514)
182 + * @since 2.0.0 bbPress (r2746)
201 183 *
202 184 * @var array
203 185 */
204 - var $db_fields = array( 'parent' => 'post_parent', 'id' => 'ID' );
186 + public $db_fields = array(
187 + 'parent' => 'post_parent',
188 + 'id' => 'ID'
189 + );
205 190
206 191 /** Methods ***************************************************************/
207 192
208 193 /**
@@ -207,9 +192,9 @@
207 192
208 193 /**
209 194 * Set the tree_type
210 195 *
211 - * @since bbPress (r2514)
196 + * @since 2.0.0 bbPress (r2746)
212 197 */
213 198 public function __construct() {
214 199 $this->tree_type = bbp_get_forum_post_type();
215 200 }
@@ -214,176 +199,313 @@
214 199 $this->tree_type = bbp_get_forum_post_type();
215 200 }
216 201
217 202 /**
218 - * @see Walker::start_lvl()
203 + * @see Walker::start_el()
219 204 *
220 - * @since bbPress (r2514)
205 + * @since 2.0.0 bbPress (r2746)
221 206 *
222 207 * @param string $output Passed by reference. Used to append additional
223 - * content.
224 - * @param int $depth Depth of page. Used for padding.
208 + * content.
209 + * @param object $object Post data object.
210 + * @param int $depth Depth of post in reference to parent posts. Used
211 + * for padding.
212 + * @param array $args Uses 'selected' argument for selected post to set
213 + * selected HTML attribute for option element.
214 + * @param int $current_object_id
225 215 */
226 - public function start_lvl( &$output, $depth ) {
227 - $indent = str_repeat( "\t", $depth );
228 - $output .= "\n$indent<ul class='children'>\n";
216 + public function start_el( &$output, $object, $depth = 0, $args = array(), $current_object_id = 0 ) {
217 + $pad = str_repeat( '&nbsp;', (int) $depth * 3 );
218 + $output .= '<option class="level-' . (int) $depth . '"';
219 +
220 + // Disable the <option> if:
221 + // - we're told to do so
222 + // - the post type is a forum
223 + // - the forum is a category
224 + // - forum is closed
225 + if ( ( true === $args['disable_categories'] )
226 + && ( bbp_get_forum_post_type() === $object->post_type )
227 + && ( bbp_is_forum_category( $object->ID )
228 + || ( ! current_user_can( 'edit_forum', $object->ID ) && bbp_is_forum_closed( $object->ID )
229 + )
230 + ) ) {
231 + $output .= ' disabled="disabled" value=""';
232 + } else {
233 + $output .= ' value="' . (int) $object->ID .'"' . selected( $args['selected'], $object->ID, false );
234 + }
235 +
236 + $output .= '>';
237 + $title = apply_filters( 'bbp_walker_dropdown_post_title', $object->post_title, $output, $object, $depth, $args );
238 + $output .= $pad . esc_html( $title );
239 + $output .= "</option>\n";
229 240 }
241 +}
230 242
243 +/**
244 + * Create hierarchical list of bbPress replies.
245 + *
246 + * @package bbPress
247 + * @subpackage Classes
248 + *
249 + * @since 2.4.0 bbPress (r4944)
250 + */
251 +class BBP_Walker_Reply extends Walker {
252 +
231 253 /**
232 - * @see Walker::end_lvl()
254 + * @see Walker::$tree_type
233 255 *
234 - * @since bbPress (r2514)
256 + * @since 2.4.0 bbPress (r4944)
235 257 *
236 - * @param string $output Passed by reference. Used to append additional
237 - * content.
238 - * @param int $depth Depth of page. Used for padding.
258 + * @var string
239 259 */
240 - public function end_lvl( &$output, $depth ) {
241 - $indent = str_repeat( "\t", $depth );
242 - $output .= "$indent</ul>\n";
260 + public $tree_type = 'reply';
261 +
262 + /**
263 + * @see Walker::$db_fields
264 + *
265 + * @since 2.4.0 bbPress (r4944)
266 + *
267 + * @var array
268 + */
269 + public $db_fields = array(
270 + 'parent' => 'reply_to',
271 + 'id' => 'ID'
272 + );
273 +
274 + /**
275 + * Confirm the tree_type
276 + *
277 + * @since 2.6.0 bbPress (r5389)
278 + */
279 + public function __construct() {
280 + $this->tree_type = bbp_get_reply_post_type();
243 281 }
244 282
245 283 /**
246 - * @see Walker::start_el()
284 + * @see Walker::start_lvl()
247 285 *
248 - * @since bbPress (r2514)
286 + * @since 2.4.0 bbPress (r4944)
249 287 *
250 - * @param string $output Passed by reference. Used to append additional
251 - * content.
252 - * @param object $forum Page data object.
253 - * @param int $depth Depth of page. Used for padding.
254 - * @param int $current_forum Page ID.
255 - * @param array $args
288 + * @param string $output Passed by reference. Used to append additional content
289 + * @param int $depth Depth of reply
290 + * @param array $args Uses 'style' argument for type of HTML list
256 291 */
257 - public function start_el( &$output, $forum, $depth, $args, $current_forum ) {
292 + public function start_lvl( &$output = '', $depth = 0, $args = array() ) {
293 + bbpress()->reply_query->reply_depth = (int) $depth + 1;
258 294
259 - $indent = $depth ? str_repeat( "\t", $depth ) : '';
295 + switch ( $args['style'] ) {
296 + case 'div':
297 + break;
298 + case 'ol':
299 + $output .= "<ol class='bbp-threaded-replies'>\n";
300 + break;
301 + case 'ul':
302 + default:
303 + $output .= "<ul class='bbp-threaded-replies'>\n";
304 + break;
305 + }
306 + }
260 307
261 - extract( $args, EXTR_SKIP );
262 - $css_class = array( 'bbp-forum-item', 'bbp-forum-item-' . $forum->ID );
308 + /**
309 + * @see Walker::end_lvl()
310 + *
311 + * @since 2.4.0 bbPress (r4944)
312 + *
313 + * @param string $output Passed by reference. Used to append additional content
314 + * @param int $depth Depth of reply
315 + * @param array $args Will only append content if style argument value is 'ol' or 'ul'
316 + */
317 + public function end_lvl( &$output = '', $depth = 0, $args = array() ) {
318 + bbpress()->reply_query->reply_depth = (int) $depth + 1;
263 319
264 - if ( !empty( $current_forum ) ) {
265 - $_current_page = bbp_get_forum( $current_forum );
320 + switch ( $args['style'] ) {
321 + case 'div':
322 + break;
323 + case 'ol':
324 + $output .= "</ol>\n";
325 + break;
326 + case 'ul':
327 + default:
328 + $output .= "</ul>\n";
329 + break;
330 + }
331 + }
266 332
267 - if ( isset( $_current_page->ancestors ) && in_array( $forum->ID, (array) $_current_page->ancestors ) )
268 - $css_class[] = 'bbp-current-forum-ancestor';
333 + /**
334 + * @since 2.4.0 bbPress (r4944)
335 + */
336 + public function display_element( $element = false, &$children_elements = array(), $max_depth = 0, $depth = 0, $args = array(), &$output = '' ) {
269 337
270 - if ( $forum->ID == $current_forum )
271 - $css_class[] = 'bbp_current_forum_item';
272 - elseif ( $_current_page && $forum->ID == $_current_page->post_parent )
273 - $css_class[] = 'bbp-current-forum-parent';
338 + if ( empty( $element ) ) {
339 + return;
340 + }
274 341
275 - } elseif ( $forum->ID == get_option( 'page_for_posts' ) ) {
276 - $css_class[] = 'bbp-current-forum-parent';
342 + // Get element's id
343 + $id_field = $this->db_fields['id'];
344 + $id = $element->$id_field;
345 +
346 + // Display element
347 + parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output );
348 +
349 + // If we're at the max depth and the current element still has children, loop over those
350 + // and display them at this level to prevent them being orphaned to the end of the list.
351 + if ( ( $max_depth <= (int) $depth + 1 ) && isset( $children_elements[ $id ] ) ) {
352 + foreach ( $children_elements[ $id ] as $child ) {
353 + $this->display_element( $child, $children_elements, $max_depth, $depth, $args, $output );
354 + }
355 + unset( $children_elements[ $id ] );
277 356 }
357 + }
278 358
279 - $css_class = implode( ' ', apply_filters( 'bbp_forum_css_class', $css_class, $forum ) );
280 - $output .= $indent . '<li class="' . $css_class . '"><a href="' . bbp_get_forum_permalink( $forum->ID ) . '" title="' . esc_attr( wp_strip_all_tags( apply_filters( 'the_title', $forum->post_title, $forum->ID ) ) ) . '">' . $link_before . apply_filters( 'the_title', $forum->post_title, $forum->ID ) . $link_after . '</a>';
359 + /**
360 + * @see Walker:start_el()
361 + *
362 + * @since 2.4.0 bbPress (r4944)
363 + */
364 + public function start_el( &$output, $object, $depth = 0, $args = array(), $current_object_id = 0 ) {
281 365
282 - if ( !empty( $show_date ) ) {
283 - $time = ( 'modified' == $show_date ) ? $forum->post_modified : $time = $forum->post_date;
284 - $output .= " " . mysql2date( $date_format, $time );
366 + // Set up reply
367 + $depth++;
368 + bbpress()->reply_query->reply_depth = (int) $depth;
369 + bbpress()->reply_query->post = $object;
370 + bbpress()->current_reply_id = $object->ID;
371 +
372 + // Check for a callback and use it if specified
373 + if ( ! empty( $args['callback'] ) ) {
374 + ob_start();
375 + call_user_func( $args['callback'], $object, $args, $depth );
376 + $output .= ob_get_clean();
377 + return;
285 378 }
379 +
380 + // Style for div or list element
381 + if ( ! empty( $args['style'] ) && ( 'div' === $args['style'] ) ) {
382 + $output .= "<div>\n";
383 + } else {
384 + $output .= "<li>\n";
385 + }
386 +
387 + $output .= bbp_buffer_template_part( 'loop', 'single-reply', false );
286 388 }
287 389
288 390 /**
289 - * @see Walker::end_el()
290 - *
291 - * @since bbPress (r2514)
292 - *
293 - * @param string $output Passed by reference. Used to append additional
294 - * content.
295 - * @param object $forum Page data object. Not used.
296 - * @param int $depth Depth of page. Not Used.
391 + * @since 2.4.0 bbPress (r4944)
297 392 */
298 - public function end_el( &$output, $forum, $depth ) {
299 - $output .= "</li>\n";
393 + public function end_el( &$output = '', $object = false, $depth = 0, $args = array() ) {
394 +
395 + // Check for a callback and use it if specified
396 + if ( ! empty( $args['end-callback'] ) ) {
397 + ob_start();
398 + call_user_func( $args['end-callback'], $object, $args, $depth );
399 + $output .= ob_get_clean();
400 + return;
401 + }
402 +
403 + // Style for div or list element
404 + if ( ! empty( $args['style'] ) && ( 'div' === $args['style'] ) ) {
405 + $output .= "</div>\n";
406 + } else {
407 + $output .= "</li>\n";
408 + }
300 409 }
301 410 }
302 411
303 412 /**
304 - * Create HTML dropdown list of bbPress forums/topics.
413 + * Create HTML dropdown list of bbPress replies.
305 414 *
306 415 * @package bbPress
307 416 * @subpackage Classes
308 417 *
309 - * @since bbPress (r2746)
310 - * @uses Walker
418 + * @since 2.6.0 bbPress (r5389)
311 419 */
312 -class BBP_Walker_Dropdown extends Walker {
420 +class BBP_Walker_Reply_Dropdown extends Walker {
313 421
314 422 /**
315 423 * @see Walker::$tree_type
316 424 *
317 - * @since bbPress (r2746)
425 + * @since 2.6.0 bbPress (r5389)
318 426 *
319 427 * @var string
320 428 */
321 - var $tree_type;
429 + public $tree_type = 'reply';
322 430
323 431 /**
324 432 * @see Walker::$db_fields
325 433 *
326 - * @since bbPress (r2746)
434 + * @since 2.6.0 bbPress (r5389)
327 435 *
328 436 * @var array
329 437 */
330 - var $db_fields = array( 'parent' => 'post_parent', 'id' => 'ID' );
438 + public $db_fields = array(
439 + 'parent' => 'reply_to',
440 + 'id' => 'ID'
441 + );
331 442
332 443 /** Methods ***************************************************************/
333 444
334 445 /**
335 - * Set the tree_type
446 + * Confirm the tree_type
336 447 *
337 - * @since bbPress (r2746)
448 + * @since 2.6.0 bbPress (r5389)
338 449 */
339 450 public function __construct() {
340 - $this->tree_type = bbp_get_forum_post_type();
451 + $this->tree_type = bbp_get_reply_post_type();
341 452 }
342 453
343 454 /**
344 455 * @see Walker::start_el()
345 456 *
346 - * @since bbPress (r2746)
457 + * @since 2.6.0 bbPress (r5389)
347 458 *
348 459 * @param string $output Passed by reference. Used to append additional
349 - * content.
350 - * @param object $_post Post data object.
351 - * @param int $depth Depth of post in reference to parent posts. Used
352 - * for padding.
353 - * @param array $args Uses 'selected' argument for selected post to set
354 - * selected HTML attribute for option element.
355 - * @uses bbp_is_forum_category() To check if the forum is a category
356 - * @uses current_user_can() To check if the current user can post in
357 - * closed forums
358 - * @uses bbp_is_forum_closed() To check if the forum is closed
359 - * @uses apply_filters() Calls 'bbp_walker_dropdown_post_title' with the
360 - * title, output, post, depth and args
460 + * content.
461 + *
462 + * @param object $object Post data object.
463 + *
464 + * @param int $depth Depth of post in reference to parent posts. Used
465 + * for padding.
466 + *
467 + * @param array $args Uses 'selected' argument for selected post to set
468 + * selected HTML attribute for option element.
469 + *
470 + * @param int $current_object_id Not Used
361 471 */
362 - public function start_el( &$output, $_post, $depth, $args ) {
363 - $pad = str_repeat( '&nbsp;', $depth * 3 );
364 - $output .= '<option class="level-' . $depth . '"';
472 + public function start_el( &$output, $object, $depth = 0, $args = array(), $current_object_id = 0 ) {
365 473
366 - // Disable the <option> if:
367 - // - we're told to do so
368 - // - the post type is a forum
369 - // - the forum is a category
370 - // - forum is closed
371 - if ( ( true == $args['disable_categories'] )
372 - && ( bbp_get_forum_post_type() == $_post->post_type )
373 - && ( bbp_is_forum_category( $_post->ID )
374 - || ( !current_user_can( 'edit_forum', $_post->ID ) && bbp_is_forum_closed( $_post->ID )
375 - )
376 - ) ) {
377 - $output .= ' disabled="disabled" value=""';
474 + // Set up reply
475 + $depth++;
476 +
477 + // Get the reply ID
478 + if ( isset( $args['exclude'][0] ) ) {
479 + $reply_id = (int) $args['exclude'][0];
378 480 } else {
379 - $output .= ' value="' . $_post->ID .'"' . selected( $args['selected'], $_post->ID, false );
481 + $reply_id = bbp_get_reply_id();
380 482 }
381 483
382 - $output .= '>';
383 - $title = apply_filters( 'bbp_walker_dropdown_post_title', $_post->post_title, $output, $_post, $depth, $args );
384 - $output .= $pad . esc_html( $title );
385 - $output .= "</option>\n";
484 + // Get ancestors to determine which items to disable
485 + $ancestors = bbp_get_reply_ancestors( $object->ID );
486 + array_push( $ancestors, $object->ID );
487 +
488 + // Determine the indentation
489 + $pad = str_repeat( '&nbsp;', (int) $depth * 3 );
490 +
491 + // Determine reply title (either post_title, or excerpt of post_content)
492 + $title = ! empty( $object->post_title ) ? $object->post_title : wp_html_excerpt( $object->post_content, 10 );
493 + $title = sprintf( esc_html__( '%1$s - %2$s', 'bbpress' ), (int) $object->ID, $title );
494 + $title = apply_filters( 'bbp_walker_dropdown_post_title', $title, $output, $object, $depth, $args );
495 +
496 + // Attributes
497 + $class = 'level-' . (int) $depth;
498 + $value = (int) $object->ID;
499 +
500 + // Start an output buffer to make late escaping easier
501 + ob_start(); ?>
502 +
503 + <option class="<?php echo esc_attr( $class ); ?>" value="<?php echo esc_attr( $value ); ?>"<?php selected( $args['selected'], $object->ID ); ?> <?php disabled( in_array( $reply_id, $ancestors ), true ); ?>><?php echo $pad . esc_html( $title ); ?></option>
504 +
505 + <?php
506 +
507 + // Append the output buffer to the $output variable
508 + $output .= ob_get_clean();
386 509 }
387 510 }
388 -
389 511 endif; // class_exists check