PluginProbe
bbPress / trunk
bbPress vtrunk
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
bbpress / includes / common / classes.php

classes.php in bbPress trunk, at includes/common/classes.php

513 lines 12.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * bbPress Classes.
5 *
6 * @package bbPress
7 * @subpackage Classes
8 */
9
10 // Exit if accessed directly
11 defined( 'ABSPATH' ) || exit;
12
13 if ( ! class_exists( 'BBP_Component' ) ) :
14 /**
15 * bbPress Component Class.
16 *
17 * The bbPress component class is responsible for simplifying the creation
18 * of components that share similar behaviors and routines. It is used
19 * internally by bbPress to create forums, topics and replies, but can be
20 * extended to create other really neat things.
21 *
22 * @package bbPress
23 * @subpackage Classes
24 *
25 * @since 2.0.0 bbPress (r2688)
26 */
27 class BBP_Component {
28
29 /**
30 * @var string Unique name (for internal identification).
31 * @internal
32 */
33 public $name;
34
35 /**
36 * @var Unique ID (normally for custom post type).
37 */
38 public $id;
39
40 /**
41 * @var string Unique slug (used in query string and permalinks).
42 */
43 public $slug;
44
45 /**
46 * @var WP_Query The loop for this component.
47 */
48 public $query;
49
50 /**
51 * @var string The current ID of the queried object.
52 */
53 public $current_id;
54
55
56 /** Methods ***************************************************************/
57
58 /**
59 * bbPress Component loader.
60 *
61 * @since 2.0.0 bbPress (r2700)
62 *
63 * @param array $args Required. Supports these args:
64 * - name: Unique name (for internal identification)
65 * - id: Unique ID (normally for custom post type)
66 * - slug: Unique slug (used in query string and permalinks)
67 * - query: The loop for this component (WP_Query)
68 * - current_id: The current ID of the queried object
69 */
70 public function __construct( $args = array() ) {
71 if ( empty( $args ) ) {
72 return;
73 }
74
75 $this->setup_globals( $args );
76 $this->includes();
77 $this->setup_actions();
78 }
79
80 /**
81 * Component global variables.
82 *
83 * @since 2.0.0 bbPress (r2700)
84 *
85 * @access private
86 */
87 private function setup_globals( $args = array() ) {
88 $this->name = $args['name'];
89 $this->id = apply_filters( 'bbp_' . $this->name . '_id', $args['id'] );
90 $this->slug = apply_filters( 'bbp_' . $this->name . '_slug', $args['slug'] );
91 }
92
93 /**
94 * Include required files.
95 *
96 * @since 2.0.0 bbPress (r2700)
97 *
98 * @access private
99 */
100 private function includes() {
101 do_action( 'bbp_' . $this->name . 'includes' );
102 }
103
104 /**
105 * Setup the actions.
106 *
107 * @since 2.0.0 bbPress (r2700)
108 *
109 * @access private
110 */
111 private function setup_actions() {
112 add_action( 'bbp_register_post_types', array( $this, 'register_post_types' ), 10, 2 ); // Register post types
113 add_action( 'bbp_register_taxonomies', array( $this, 'register_taxonomies' ), 10, 2 ); // Register taxonomies
114 add_action( 'bbp_add_rewrite_tags', array( $this, 'add_rewrite_tags' ), 10, 2 ); // Add the rewrite tags
115 add_action( 'bbp_generate_rewrite_rules', array( $this, 'generate_rewrite_rules' ), 10, 2 ); // Generate rewrite rules
116
117 // Additional actions can be attached here
118 do_action( 'bbp_' . $this->name . 'setup_actions' );
119 }
120
121 /**
122 * Setup the component post types.
123 *
124 * @since 2.0.0 bbPress (r2700)
125 */
126 public function register_post_types() {
127 do_action( 'bbp_' . $this->name . '_register_post_types' );
128 }
129
130 /**
131 * Register component specific taxonomies.
132 *
133 * @since 2.0.0 bbPress (r2700)
134 */
135 public function register_taxonomies() {
136 do_action( 'bbp_' . $this->name . '_register_taxonomies' );
137 }
138
139 /**
140 * Add any additional rewrite tags.
141 *
142 * @since 2.0.0 bbPress (r2700)
143 */
144 public function add_rewrite_tags() {
145 do_action( 'bbp_' . $this->name . '_add_rewrite_tags' );
146 }
147
148 /**
149 * Generate any additional rewrite rules.
150 *
151 * @since 2.0.0 bbPress (r2700)
152 */
153 public function generate_rewrite_rules( $wp_rewrite ) {
154 do_action_ref_array( 'bbp_' . $this->name . '_generate_rewrite_rules', $wp_rewrite );
155 }
156 }
157 endif; // BBP_Component
158
159 if ( class_exists( 'Walker' ) ) :
160 /**
161 * Create HTML dropdown list of bbPress forums/topics.
162 *
163 * @package bbPress
164 * @subpackage Classes
165 *
166 * @since 2.0.0 bbPress (r2746)
167 */
168 class BBP_Walker_Dropdown extends Walker {
169
170 /**
171 * @see Walker::$tree_type
172 *
173 * @since 2.0.0 bbPress (r2746)
174 *
175 * @var string
176 */
177 public $tree_type = 'forum';
178
179 /**
180 * @see Walker::$db_fields
181 *
182 * @since 2.0.0 bbPress (r2746)
183 *
184 * @var array
185 */
186 public $db_fields = array(
187 'parent' => 'post_parent',
188 'id' => 'ID'
189 );
190
191 /** Methods ***************************************************************/
192
193 /**
194 * Set the tree_type.
195 *
196 * @since 2.0.0 bbPress (r2746)
197 */
198 public function __construct() {
199 $this->tree_type = bbp_get_forum_post_type();
200 }
201
202 /**
203 * @see Walker::start_el()
204 *
205 * @since 2.0.0 bbPress (r2746)
206 *
207 * @param string $output Passed by reference. Used to append additional
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
215 */
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";
240 }
241 }
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
253 /**
254 * @see Walker::$tree_type
255 *
256 * @since 2.4.0 bbPress (r4944)
257 *
258 * @var string
259 */
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();
281 }
282
283 /**
284 * @see Walker::start_lvl()
285 *
286 * @since 2.4.0 bbPress (r4944)
287 *
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.
291 */
292 public function start_lvl( &$output = '', $depth = 0, $args = array() ) {
293 bbpress()->reply_query->reply_depth = (int) $depth + 1;
294
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 }
307
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;
319
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 }
332
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 = '' ) {
337
338 if ( empty( $element ) ) {
339 return;
340 }
341
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 ] );
356 }
357 }
358
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 ) {
365
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;
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 );
388 }
389
390 /**
391 * @since 2.4.0 bbPress (r4944)
392 */
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 }
409 }
410 }
411
412 /**
413 * Create HTML dropdown list of bbPress replies.
414 *
415 * @package bbPress
416 * @subpackage Classes
417 *
418 * @since 2.6.0 bbPress (r5389)
419 */
420 class BBP_Walker_Reply_Dropdown extends Walker {
421
422 /**
423 * @see Walker::$tree_type
424 *
425 * @since 2.6.0 bbPress (r5389)
426 *
427 * @var string
428 */
429 public $tree_type = 'reply';
430
431 /**
432 * @see Walker::$db_fields
433 *
434 * @since 2.6.0 bbPress (r5389)
435 *
436 * @var array
437 */
438 public $db_fields = array(
439 'parent' => 'reply_to',
440 'id' => 'ID'
441 );
442
443 /** Methods ***************************************************************/
444
445 /**
446 * Confirm the tree_type.
447 *
448 * @since 2.6.0 bbPress (r5389)
449 */
450 public function __construct() {
451 $this->tree_type = bbp_get_reply_post_type();
452 }
453
454 /**
455 * @see Walker::start_el()
456 *
457 * @since 2.6.0 bbPress (r5389)
458 *
459 * @param string $output Passed by reference. Used to append additional
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.
471 */
472 public function start_el( &$output, $object, $depth = 0, $args = array(), $current_object_id = 0 ) {
473
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];
480 } else {
481 $reply_id = bbp_get_reply_id();
482 }
483
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 /* translators: 1: Reply ID, 2: Reply title */
494 $title = sprintf( esc_html__( '%1$s - %2$s', 'bbpress' ), (int) $object->ID, $title );
495 $title = apply_filters( 'bbp_walker_dropdown_post_title', $title, $output, $object, $depth, $args );
496
497 // Attributes
498 $class = 'level-' . (int) $depth;
499 $value = (int) $object->ID;
500
501 // Start an output buffer to make late escaping easier
502 ob_start(); ?>
503
504 <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 ), true ); ?>><?php echo $pad . esc_html( $title ); ?></option>
505
506 <?php
507
508 // Append the output buffer to the $output variable
509 $output .= ob_get_clean();
510 }
511 }
512 endif; // class_exists check
513