web/wp-content/plugins/bbpress/includes/core/template-functions.php
changeset 196 5e8dcbe22c24
equal deleted inserted replaced
195:c7c0fbc09788 196:5e8dcbe22c24
       
     1 <?php
       
     2 
       
     3 /**
       
     4  * bbPress Template Functions
       
     5  *
       
     6  * This file contains functions necessary to mirror the WordPress core template
       
     7  * loading process. Many of those functions are not filterable, and even then
       
     8  * would not be robust enough to predict where bbPress templates might exist.
       
     9  *
       
    10  * @package bbPress
       
    11  * @subpackage TemplateFunctions
       
    12  */
       
    13 
       
    14 // Exit if accessed directly
       
    15 if ( !defined( 'ABSPATH' ) ) exit;
       
    16 
       
    17 /**
       
    18  * Adds bbPress theme support to any active WordPress theme
       
    19  *
       
    20  * @since bbPress (r3032)
       
    21  *
       
    22  * @param string $slug
       
    23  * @param string $name Optional. Default null
       
    24  * @uses bbp_locate_template()
       
    25  * @uses load_template()
       
    26  * @uses get_template_part()
       
    27  */
       
    28 function bbp_get_template_part( $slug, $name = null ) {
       
    29 
       
    30 	// Execute code for this part
       
    31 	do_action( 'get_template_part_' . $slug, $slug, $name );
       
    32 
       
    33 	// Setup possible parts
       
    34 	$templates = array();
       
    35 	if ( isset( $name ) )
       
    36 		$templates[] = $slug . '-' . $name . '.php';
       
    37 	$templates[] = $slug . '.php';
       
    38 
       
    39 	// Allow template parst to be filtered
       
    40 	$templates = apply_filters( 'bbp_get_template_part', $templates, $slug, $name );
       
    41 
       
    42 	// Return the part that is found
       
    43 	return bbp_locate_template( $templates, true, false );
       
    44 }
       
    45 
       
    46 /**
       
    47  * Retrieve the name of the highest priority template file that exists.
       
    48  *
       
    49  * Searches in the child theme before parent theme so that themes which
       
    50  * inherit from a parent theme can just overload one file. If the template is
       
    51  * not found in either of those, it looks in the theme-compat folder last.
       
    52  *
       
    53  * @since bbPres (r3618)
       
    54  *
       
    55  * @param string|array $template_names Template file(s) to search for, in order.
       
    56  * @param bool $load If true the template file will be loaded if it is found.
       
    57  * @param bool $require_once Whether to require_once or require. Default true.
       
    58  *                            Has no effect if $load is false.
       
    59  * @return string The template filename if one is located.
       
    60  */
       
    61 function bbp_locate_template( $template_names, $load = false, $require_once = true ) {
       
    62 
       
    63 	// No file found yet
       
    64 	$located            = false;
       
    65 	$template_locations = bbp_get_template_stack();
       
    66 
       
    67 	// Try to find a template file
       
    68 	foreach ( (array) $template_names as $template_name ) {
       
    69 
       
    70 		// Continue if template is empty
       
    71 		if ( empty( $template_name ) )
       
    72 			continue;
       
    73 
       
    74 		// Trim off any slashes from the template name
       
    75 		$template_name  = ltrim( $template_name, '/' );
       
    76 
       
    77 		// Loop through template stack
       
    78 		foreach ( (array) $template_locations as $template_location ) {
       
    79 
       
    80 			// Continue if $template_location is empty
       
    81 			if ( empty( $template_location ) )
       
    82 				continue;
       
    83 
       
    84 			// Check child theme first
       
    85 			if ( file_exists( trailingslashit( $template_location ) . $template_name ) ) {
       
    86 				$located = trailingslashit( $template_location ) . $template_name;
       
    87 				break 2;
       
    88 			}
       
    89 		}
       
    90 	}
       
    91 
       
    92 	// Maybe load the template if one was located
       
    93 	if ( ( true == $load ) && !empty( $located ) )
       
    94 		load_template( $located, $require_once );
       
    95 
       
    96 	return $located;
       
    97 }
       
    98 
       
    99 /**
       
   100  * This is really cool. This function registers a new template stack location,
       
   101  * using WordPress's built in filters API.
       
   102  *
       
   103  * This allows for templates to live in places beyond just the parent/child
       
   104  * relationship, to allow for custom template locations. Used in conjunction
       
   105  * with bbp_locate_template(), this allows for easy template overrides.
       
   106  *
       
   107  * @since bbPress (r4323)
       
   108  *
       
   109  * @param string $location Callback function that returns the 
       
   110  * @param int $priority
       
   111  */
       
   112 function bbp_register_template_stack( $location_callback = '', $priority = 10 ) {
       
   113 
       
   114 	// Bail if no location, or function does not exist
       
   115 	if ( empty( $location_callback ) || ! function_exists( $location_callback ) )
       
   116 		return false;
       
   117 
       
   118 	// Add location callback to template stack
       
   119 	add_filter( 'bbp_template_stack', $location_callback, (int) $priority );
       
   120 }
       
   121 
       
   122 /**
       
   123  * Call the functions added to the 'bbp_template_stack' filter hook, and return
       
   124  * an array of the template locations.
       
   125  *
       
   126  * @see bbp_register_template_stack()
       
   127  *
       
   128  * @since bbPress (r4323)
       
   129  *
       
   130  * @global array $wp_filter Stores all of the filters
       
   131  * @global array $merged_filters Merges the filter hooks using this function.
       
   132  * @global array $wp_current_filter stores the list of current filters with the current one last
       
   133  *
       
   134  * @return array The filtered value after all hooked functions are applied to it.
       
   135  */
       
   136 function bbp_get_template_stack() {
       
   137 	global $wp_filter, $merged_filters, $wp_current_filter;
       
   138 
       
   139 	// Setup some default variables
       
   140 	$tag  = 'bbp_template_stack';
       
   141 	$args = $stack = array();
       
   142 
       
   143 	// Add 'bbp_template_stack' to the current filter array
       
   144 	$wp_current_filter[] = $tag;
       
   145 
       
   146 	// Sort
       
   147 	if ( ! isset( $merged_filters[ $tag ] ) ) {
       
   148 		ksort( $wp_filter[$tag] );
       
   149 		$merged_filters[ $tag ] = true;
       
   150 	}
       
   151 
       
   152 	// Ensure we're always at the beginning of the filter array
       
   153 	reset( $wp_filter[ $tag ] );
       
   154 
       
   155 	// Loop through 'bbp_template_stack' filters, and call callback functions
       
   156 	do {
       
   157 		foreach( (array) current( $wp_filter[$tag] ) as $the_ ) {
       
   158 			if ( ! is_null( $the_['function'] ) ) {
       
   159 				$args[1] = $stack;
       
   160 				$stack[] = call_user_func_array( $the_['function'], array_slice( $args, 1, (int) $the_['accepted_args'] ) );
       
   161 			}
       
   162 		}
       
   163 	} while ( next( $wp_filter[$tag] ) !== false );
       
   164 
       
   165 	// Remove 'bbp_template_stack' from the current filter array
       
   166 	array_pop( $wp_current_filter );
       
   167 
       
   168 	// Remove empties and duplicates
       
   169 	$stack = array_unique( array_filter( $stack ) );
       
   170 
       
   171 	return (array) apply_filters( 'bbp_get_template_stack', $stack ) ;
       
   172 }
       
   173 
       
   174 /**
       
   175  * Retrieve path to a template
       
   176  *
       
   177  * Used to quickly retrieve the path of a template without including the file
       
   178  * extension. It will also check the parent theme and theme-compat theme with
       
   179  * the use of {@link bbp_locate_template()}. Allows for more generic template
       
   180  * locations without the use of the other get_*_template() functions.
       
   181  *
       
   182  * @since bbPress (r3629)
       
   183  *
       
   184  * @param string $type Filename without extension.
       
   185  * @param array $templates An optional list of template candidates
       
   186  * @uses bbp_set_theme_compat_templates()
       
   187  * @uses bbp_locate_template()
       
   188  * @uses bbp_set_theme_compat_template()
       
   189  * @return string Full path to file.
       
   190  */
       
   191 function bbp_get_query_template( $type, $templates = array() ) {
       
   192 	$type = preg_replace( '|[^a-z0-9-]+|', '', $type );
       
   193 
       
   194 	if ( empty( $templates ) )
       
   195 		$templates = array( "{$type}.php" );
       
   196 
       
   197 	// Filter possible templates, try to match one, and set any bbPress theme
       
   198 	// compat properties so they can be cross-checked later.
       
   199 	$templates = apply_filters( "bbp_get_{$type}_template", $templates );
       
   200 	$templates = bbp_set_theme_compat_templates( $templates );
       
   201 	$template  = bbp_locate_template( $templates );
       
   202 	$template  = bbp_set_theme_compat_template( $template );
       
   203 
       
   204 	return apply_filters( "bbp_{$type}_template", $template );
       
   205 }
       
   206 
       
   207 /**
       
   208  * Get the possible subdirectories to check for templates in
       
   209  *
       
   210  * @since bbPress (r3738)
       
   211  * @param array $templates Templates we are looking for
       
   212  * @return array Possible subfolders to look in
       
   213  */
       
   214 function bbp_get_template_locations( $templates = array() ) {
       
   215 	$locations = array(
       
   216 		'bbpress',
       
   217 		'forums',
       
   218 		''
       
   219 	);
       
   220 	return apply_filters( 'bbp_get_template_locations', $locations, $templates );
       
   221 }
       
   222 
       
   223 /**
       
   224  * Add template locations to template files being searched for
       
   225  *
       
   226  * @since bbPress (r3738)
       
   227  *
       
   228  * @param array $templates
       
   229  * @return array() 
       
   230  */
       
   231 function bbp_add_template_locations( $templates = array() ) {
       
   232 	$retval = array();
       
   233 
       
   234 	// Get alternate locations
       
   235 	$locations = bbp_get_template_locations( $templates );
       
   236 
       
   237 	// Loop through locations and templates and combine
       
   238 	foreach ( (array) $locations as $location )
       
   239 		foreach ( (array) $templates as $template )
       
   240 			$retval[] = ltrim( trailingslashit( $location ) . $template, '/' );
       
   241 
       
   242 	return apply_filters( 'bbp_add_template_locations', array_unique( $retval ), $templates );
       
   243 }
       
   244 
       
   245 /**
       
   246  * Add checks for bbPress conditions to parse_query action
       
   247  *
       
   248  * If it's a user page, WP_Query::bbp_is_single_user is set to true.
       
   249  * If it's a user edit page, WP_Query::bbp_is_single_user_edit is set to true
       
   250  * and the the 'wp-admin/includes/user.php' file is included.
       
   251  * In addition, on user/user edit pages, WP_Query::home is set to false & query
       
   252  * vars 'bbp_user_id' with the displayed user id and 'author_name' with the
       
   253  * displayed user's nicename are added.
       
   254  *
       
   255  * If it's a forum edit, WP_Query::bbp_is_forum_edit is set to true
       
   256  * If it's a topic edit, WP_Query::bbp_is_topic_edit is set to true
       
   257  * If it's a reply edit, WP_Query::bbp_is_reply_edit is set to true.
       
   258  *
       
   259  * If it's a view page, WP_Query::bbp_is_view is set to true
       
   260  *
       
   261  * @since bbPress (r2688)
       
   262  *
       
   263  * @param WP_Query $posts_query
       
   264  *
       
   265  * @uses get_query_var() To get {@link WP_Query} query var
       
   266  * @uses is_email() To check if the string is an email
       
   267  * @uses get_user_by() To try to get the user by email and nicename
       
   268  * @uses get_userdata() to get the user data
       
   269  * @uses current_user_can() To check if the current user can edit the user
       
   270  * @uses is_user_member_of_blog() To check if user profile page exists
       
   271  * @uses WP_Query::set_404() To set a 404 status
       
   272  * @uses apply_filters() Calls 'enable_edit_any_user_configuration' with true
       
   273  * @uses bbp_get_view_query_args() To get the view query args
       
   274  * @uses bbp_get_forum_post_type() To get the forum post type
       
   275  * @uses bbp_get_topic_post_type() To get the topic post type
       
   276  * @uses bbp_get_reply_post_type() To get the reply post type
       
   277  * @uses remove_action() To remove the auto save post revision action
       
   278  */
       
   279 function bbp_parse_query( $posts_query ) {
       
   280 
       
   281 	// Bail if $posts_query is not the main loop
       
   282 	if ( ! $posts_query->is_main_query() )
       
   283 		return;
       
   284 
       
   285 	// Bail if filters are suppressed on this query
       
   286 	if ( true == $posts_query->get( 'suppress_filters' ) )
       
   287 		return;
       
   288 
       
   289 	// Bail if in admin
       
   290 	if ( is_admin() )
       
   291 		return;
       
   292 
       
   293 	// Get query variables
       
   294 	$bbp_view = $posts_query->get( bbp_get_view_rewrite_id() );
       
   295 	$bbp_user = $posts_query->get( bbp_get_user_rewrite_id() );
       
   296 	$is_edit  = $posts_query->get( bbp_get_edit_rewrite_id() );
       
   297 
       
   298 	// It is a user page - We'll also check if it is user edit
       
   299 	if ( !empty( $bbp_user ) ) {
       
   300 
       
   301 		// Not a user_id so try email and slug
       
   302 		if ( !is_numeric( $bbp_user ) ) {
       
   303 
       
   304 			// Email was passed
       
   305 			if ( is_email( $bbp_user ) ) {
       
   306 				$bbp_user = get_user_by( 'email', $bbp_user );
       
   307 
       
   308 			// Try nicename
       
   309 			} else {
       
   310 				$bbp_user = get_user_by( 'slug', $bbp_user );
       
   311 			}
       
   312 
       
   313 			// If we were successful, set to ID
       
   314 			if ( is_object( $bbp_user ) ) {
       
   315 				$bbp_user = $bbp_user->ID;
       
   316 			}
       
   317 		}
       
   318 
       
   319 		// Cast as int, just in case
       
   320 		$bbp_user = (int) $bbp_user;
       
   321 
       
   322 		// 404 and bail if user does not have a profile
       
   323 		if ( ! bbp_user_has_profile( $bbp_user ) ) {
       
   324 			$posts_query->set_404();
       
   325 			return;
       
   326 		}
       
   327 
       
   328 		/** User Exists *******************************************************/
       
   329 
       
   330 		$is_favs    = $posts_query->get( bbp_get_user_favorites_rewrite_id()     );
       
   331 		$is_subs    = $posts_query->get( bbp_get_user_subscriptions_rewrite_id() );
       
   332 		$is_topics  = $posts_query->get( bbp_get_user_topics_rewrite_id()        );
       
   333 		$is_replies = $posts_query->get( bbp_get_user_replies_rewrite_id()       );
       
   334 
       
   335 		// View or edit?
       
   336 		if ( !empty( $is_edit ) ) {
       
   337 
       
   338 			// We are editing a profile
       
   339 			$posts_query->bbp_is_single_user_edit = true;
       
   340 
       
   341 			// Load the core WordPress contact methods
       
   342 			if ( !function_exists( '_wp_get_user_contactmethods' ) ) {
       
   343 				include_once( ABSPATH . 'wp-includes/registration.php' );
       
   344 			}
       
   345 
       
   346 			// Load the edit_user functions
       
   347 			if ( !function_exists( 'edit_user' ) ) {
       
   348 				require_once( ABSPATH . 'wp-admin/includes/user.php' );
       
   349 			}
       
   350 
       
   351 			// Load the grant/revoke super admin functions
       
   352 			if ( is_multisite() && !function_exists( 'revoke_super_admin' ) ) {
       
   353 				require_once( ABSPATH . 'wp-admin/includes/ms.php' );
       
   354 			}
       
   355 
       
   356 			// Editing a user
       
   357 			$posts_query->bbp_is_edit = true;
       
   358 
       
   359 		// User favorites
       
   360 		} elseif ( ! empty( $is_favs ) ) {
       
   361 			$posts_query->bbp_is_single_user_favs = true;
       
   362 
       
   363 		// User subscriptions
       
   364 		} elseif ( ! empty( $is_subs ) ) {
       
   365 			$posts_query->bbp_is_single_user_subs = true;
       
   366 
       
   367 		// User topics
       
   368 		} elseif ( ! empty( $is_topics ) ) {
       
   369 			$posts_query->bbp_is_single_user_topics = true;
       
   370 
       
   371 		// User topics
       
   372 		} elseif ( ! empty( $is_replies ) ) {
       
   373 			$posts_query->bbp_is_single_user_replies = true;
       
   374 
       
   375 		// User profile
       
   376 		} else {
       
   377 			$posts_query->bbp_is_single_user_profile = true;
       
   378 		}
       
   379 
       
   380 		// Looking at a single user
       
   381 		$posts_query->bbp_is_single_user = true;
       
   382 
       
   383 		// Make sure 404 is not set
       
   384 		$posts_query->is_404  = false;
       
   385 
       
   386 		// Correct is_home variable
       
   387 		$posts_query->is_home = false;
       
   388 
       
   389 		// Get the user data
       
   390 		$user = get_userdata( $bbp_user );
       
   391 
       
   392 		// User is looking at their own profile
       
   393 		if ( get_current_user_id() == $user->ID ) {
       
   394 			$posts_query->bbp_is_single_user_home = true;
       
   395 		}
       
   396 
       
   397 		// Set bbp_user_id for future reference
       
   398 		$posts_query->set( 'bbp_user_id', $user->ID );
       
   399 
       
   400 		// Set author_name as current user's nicename to get correct posts
       
   401 		$posts_query->set( 'author_name', $user->user_nicename );
       
   402 
       
   403 		// Set the displayed user global to this user
       
   404 		bbpress()->displayed_user = $user;
       
   405 
       
   406 	// View Page
       
   407 	} elseif ( !empty( $bbp_view ) ) {
       
   408 
       
   409 		// Check if the view exists by checking if there are query args are set
       
   410 		$view_args = bbp_get_view_query_args( $bbp_view );
       
   411 
       
   412 		// Bail if view args is false (view isn't registered)
       
   413 		if ( false === $view_args ) {
       
   414 			$posts_query->set_404();
       
   415 			return;
       
   416 		}
       
   417 
       
   418 		// Correct is_home variable
       
   419 		$posts_query->is_home     = false;
       
   420 
       
   421 		// We are in a custom topic view
       
   422 		$posts_query->bbp_is_view = true;
       
   423 
       
   424 	// Forum/Topic/Reply Edit Page
       
   425 	} elseif ( !empty( $is_edit ) ) {
       
   426 
       
   427 		// Get the post type from the main query loop
       
   428 		$post_type = $posts_query->get( 'post_type' );
       
   429 		
       
   430 		// Check which post_type we are editing, if any
       
   431 		if ( !empty( $post_type ) ) {
       
   432 			switch( $post_type ) {
       
   433 
       
   434 				// We are editing a forum
       
   435 				case bbp_get_forum_post_type() :
       
   436 					$posts_query->bbp_is_forum_edit = true;
       
   437 					$posts_query->bbp_is_edit       = true;
       
   438 					break;
       
   439 
       
   440 				// We are editing a topic
       
   441 				case bbp_get_topic_post_type() :
       
   442 					$posts_query->bbp_is_topic_edit = true;
       
   443 					$posts_query->bbp_is_edit       = true;
       
   444 					break;
       
   445 
       
   446 				// We are editing a reply
       
   447 				case bbp_get_reply_post_type() :
       
   448 					$posts_query->bbp_is_reply_edit = true;
       
   449 					$posts_query->bbp_is_edit       = true;
       
   450 					break;
       
   451 			}
       
   452 
       
   453 		// We are editing a topic tag
       
   454 		} elseif ( bbp_is_topic_tag() ) {
       
   455 			$posts_query->bbp_is_topic_tag_edit = true;
       
   456 			$posts_query->bbp_is_edit           = true;
       
   457 		}
       
   458 
       
   459 		// We save post revisions on our own
       
   460 		remove_action( 'pre_post_update', 'wp_save_post_revision' );
       
   461 
       
   462 	// Topic tag page
       
   463 	} elseif ( bbp_is_topic_tag() ) {
       
   464 		$posts_query->set( 'bbp_topic_tag',  get_query_var( 'term' )   );
       
   465 		$posts_query->set( 'post_type',      bbp_get_topic_post_type() );
       
   466 		$posts_query->set( 'posts_per_page', bbp_get_topics_per_page() );
       
   467 	}
       
   468 }