BP_Legacy

Loads BuddyPress Legacy Theme functionality.

Defined (1)

The class is defined in the following location(s).

/bp-templates/bp-legacy/buddypress-functions.php  
  1. class BP_Legacy extends BP_Theme_Compat { 
  2.  
  3. /** Functions *************************************************************/ 
  4.  
  5. /** 
  6. * The main BuddyPress (Legacy) Loader. 
  7. * @since 1.7.0 
  8. */ 
  9. public function __construct() { 
  10. parent::start(); 
  11.  
  12. /** 
  13. * Component global variables. 
  14. * You'll want to customize the values in here, so they match whatever your 
  15. * needs are. 
  16. * @since 1.7.0 
  17. */ 
  18. protected function setup_globals() { 
  19. $bp = buddypress(); 
  20. $this->id = 'legacy'; 
  21. $this->name = __( 'BuddyPress Legacy', 'buddypress' ); 
  22. $this->version = bp_get_version(); 
  23. $this->dir = trailingslashit( $bp->themes_dir . '/bp-legacy' ); 
  24. $this->url = trailingslashit( $bp->themes_url . '/bp-legacy' ); 
  25.  
  26. /** 
  27. * Setup the theme hooks. 
  28. * @since 1.7.0 
  29. */ 
  30. protected function setup_actions() { 
  31.  
  32. // Template Output. 
  33. add_filter( 'bp_get_activity_action_pre_meta', array( $this, 'secondary_avatars' ), 10, 2 ); 
  34.  
  35. // Filter BuddyPress template hierarchy and look for page templates. 
  36. add_filter( 'bp_get_buddypress_template', array( $this, 'theme_compat_page_templates' ), 10, 1 ); 
  37.  
  38. /** Scripts ***********************************************************/ 
  39.  
  40. add_action( 'bp_enqueue_scripts', array( $this, 'enqueue_styles' ) ); // Enqueue theme CSS 
  41. add_action( 'bp_enqueue_scripts', array( $this, 'enqueue_scripts' ) ); // Enqueue theme JS 
  42. add_filter( 'bp_enqueue_scripts', array( $this, 'localize_scripts' ) ); // Enqueue theme script localization 
  43.  
  44. /** Body no-js Class **************************************************/ 
  45.  
  46. add_filter( 'body_class', array( $this, 'add_nojs_body_class' ), 20, 1 ); 
  47.  
  48. /** Buttons ***********************************************************/ 
  49.  
  50. if ( ! is_admin() || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) { 
  51. // Register buttons for the relevant component templates 
  52. // Friends button. 
  53. if ( bp_is_active( 'friends' ) ) 
  54. add_action( 'bp_member_header_actions', 'bp_add_friend_button', 5 ); 
  55.  
  56. // Activity button. 
  57. if ( bp_is_active( 'activity' ) && bp_activity_do_mentions() ) 
  58. add_action( 'bp_member_header_actions', 'bp_send_public_message_button', 20 ); 
  59.  
  60. // Messages button. 
  61. if ( bp_is_active( 'messages' ) ) 
  62. add_action( 'bp_member_header_actions', 'bp_send_private_message_button', 20 ); 
  63.  
  64. // Group buttons. 
  65. if ( bp_is_active( 'groups' ) ) { 
  66. add_action( 'bp_group_header_actions', 'bp_group_join_button', 5 ); 
  67. add_action( 'bp_group_header_actions', 'bp_group_new_topic_button', 20 ); 
  68. add_action( 'bp_directory_groups_actions', 'bp_group_join_button' ); 
  69. add_action( 'bp_groups_directory_group_filter', 'bp_legacy_theme_group_create_nav', 999 ); 
  70. add_action( 'bp_after_group_admin_content', 'bp_legacy_groups_admin_screen_hidden_input' ); 
  71. add_action( 'bp_before_group_admin_form', 'bp_legacy_theme_group_manage_members_add_search' ); 
  72.  
  73. // Blog button. 
  74. if ( bp_is_active( 'blogs' ) ) { 
  75. add_action( 'bp_directory_blogs_actions', 'bp_blogs_visit_blog_button' ); 
  76. add_action( 'bp_blogs_directory_blog_types', 'bp_legacy_theme_blog_create_nav', 999 ); 
  77.  
  78. /** Notices ***********************************************************/ 
  79.  
  80. // Only hook the 'sitewide_notices' overlay if the Sitewide 
  81. // Notices widget is not in use (to avoid duplicate content). 
  82. if ( bp_is_active( 'messages' ) && ! is_active_widget( false, false, 'bp_messages_sitewide_notices_widget', true ) ) { 
  83. add_action( 'wp_footer', array( $this, 'sitewide_notices' ), 9999 ); 
  84.  
  85. /** Ajax **************************************************************/ 
  86.  
  87. $actions = array( 
  88.  
  89. // Directory filters. 
  90. 'blogs_filter' => 'bp_legacy_theme_object_template_loader',  
  91. 'forums_filter' => 'bp_legacy_theme_object_template_loader',  
  92. 'groups_filter' => 'bp_legacy_theme_object_template_loader',  
  93. 'members_filter' => 'bp_legacy_theme_object_template_loader',  
  94. 'messages_filter' => 'bp_legacy_theme_messages_template_loader',  
  95. 'invite_filter' => 'bp_legacy_theme_invite_template_loader',  
  96. 'requests_filter' => 'bp_legacy_theme_requests_template_loader',  
  97.  
  98. // Friends. 
  99. 'accept_friendship' => 'bp_legacy_theme_ajax_accept_friendship',  
  100. 'addremove_friend' => 'bp_legacy_theme_ajax_addremove_friend',  
  101. 'reject_friendship' => 'bp_legacy_theme_ajax_reject_friendship',  
  102.  
  103. // Activity. 
  104. 'activity_get_older_updates' => 'bp_legacy_theme_activity_template_loader',  
  105. 'activity_mark_fav' => 'bp_legacy_theme_mark_activity_favorite',  
  106. 'activity_mark_unfav' => 'bp_legacy_theme_unmark_activity_favorite',  
  107. 'activity_widget_filter' => 'bp_legacy_theme_activity_template_loader',  
  108. 'delete_activity' => 'bp_legacy_theme_delete_activity',  
  109. 'delete_activity_comment' => 'bp_legacy_theme_delete_activity_comment',  
  110. 'get_single_activity_content' => 'bp_legacy_theme_get_single_activity_content',  
  111. 'new_activity_comment' => 'bp_legacy_theme_new_activity_comment',  
  112. 'post_update' => 'bp_legacy_theme_post_update',  
  113. 'bp_spam_activity' => 'bp_legacy_theme_spam_activity',  
  114. 'bp_spam_activity_comment' => 'bp_legacy_theme_spam_activity',  
  115.  
  116. // Groups. 
  117. 'groups_invite_user' => 'bp_legacy_theme_ajax_invite_user',  
  118. 'joinleave_group' => 'bp_legacy_theme_ajax_joinleave_group',  
  119.  
  120. // Messages. 
  121. 'messages_autocomplete_results' => 'bp_legacy_theme_ajax_messages_autocomplete_results',  
  122. 'messages_close_notice' => 'bp_legacy_theme_ajax_close_notice',  
  123. 'messages_delete' => 'bp_legacy_theme_ajax_messages_delete',  
  124. 'messages_markread' => 'bp_legacy_theme_ajax_message_markread',  
  125. 'messages_markunread' => 'bp_legacy_theme_ajax_message_markunread',  
  126. 'messages_send_reply' => 'bp_legacy_theme_ajax_messages_send_reply',  
  127. ); 
  128.  
  129. // Conditional actions. 
  130. if ( bp_is_active( 'messages', 'star' ) ) { 
  131. $actions['messages_star'] = 'bp_legacy_theme_ajax_messages_star_handler'; 
  132.  
  133. /** 
  134. * Register all of these AJAX handlers. 
  135. * The "wp_ajax_" action is used for logged in users, and "wp_ajax_nopriv_" 
  136. * executes for users that aren't logged in. This is for backpat with BP <1.6. 
  137. */ 
  138. foreach( $actions as $name => $function ) { 
  139. add_action( 'wp_ajax_' . $name, $function ); 
  140. add_action( 'wp_ajax_nopriv_' . $name, $function ); 
  141.  
  142. add_filter( 'bp_ajax_querystring', 'bp_legacy_theme_ajax_querystring', 10, 2 ); 
  143.  
  144. /** Override **********************************************************/ 
  145.  
  146. /** 
  147. * Fires after all of the BuddyPress theme compat actions have been added. 
  148. * @since 1.7.0 
  149. * @param BP_Legacy $this Current BP_Legacy instance. 
  150. */ 
  151. do_action_ref_array( 'bp_theme_compat_actions', array( &$this ) ); 
  152.  
  153. /** 
  154. * Load the theme CSS 
  155. * @since 1.7.0 
  156. * @since 2.3.0 Support custom CSS file named after the current theme or parent theme. 
  157. */ 
  158. public function enqueue_styles() { 
  159. $min = bp_core_get_minified_asset_suffix(); 
  160.  
  161. // Locate the BP stylesheet. 
  162. $ltr = $this->locate_asset_in_stack( "buddypress{$min}.css", 'css' ); 
  163.  
  164. // LTR. 
  165. if ( ! is_rtl() && isset( $ltr['location'], $ltr['handle'] ) ) { 
  166. wp_enqueue_style( $ltr['handle'], $ltr['location'], array(), $this->version, 'screen' ); 
  167.  
  168. if ( $min ) { 
  169. wp_style_add_data( $ltr['handle'], 'suffix', $min ); 
  170.  
  171. // RTL. 
  172. if ( is_rtl() ) { 
  173. $rtl = $this->locate_asset_in_stack( "buddypress-rtl{$min}.css", 'css' ); 
  174.  
  175. if ( isset( $rtl['location'], $rtl['handle'] ) ) { 
  176. $rtl['handle'] = str_replace( '-css', '-css-rtl', $rtl['handle'] ); // Backwards compatibility. 
  177. wp_enqueue_style( $rtl['handle'], $rtl['location'], array(), $this->version, 'screen' ); 
  178.  
  179. if ( $min ) { 
  180. wp_style_add_data( $rtl['handle'], 'suffix', $min ); 
  181.  
  182. // Compatibility stylesheets for specific themes. 
  183. $theme = $this->locate_asset_in_stack( get_template() . "{$min}.css", 'css' ); 
  184. if ( ! is_rtl() && isset( $theme['location'] ) ) { 
  185. // Use a unique handle. 
  186. $theme['handle'] = 'bp-' . get_template(); 
  187. wp_enqueue_style( $theme['handle'], $theme['location'], array(), $this->version, 'screen' ); 
  188.  
  189. if ( $min ) { 
  190. wp_style_add_data( $theme['handle'], 'suffix', $min ); 
  191.  
  192. // Compatibility stylesheet for specific themes, RTL-version. 
  193. if ( is_rtl() ) { 
  194. $theme_rtl = $this->locate_asset_in_stack( get_template() . "-rtl{$min}.css", 'css' ); 
  195.  
  196. if ( isset( $theme_rtl['location'] ) ) { 
  197. $theme_rtl['handle'] = $theme['handle'] . '-rtl'; 
  198. wp_enqueue_style( $theme_rtl['handle'], $theme_rtl['location'], array(), $this->version, 'screen' ); 
  199.  
  200. if ( $min ) { 
  201. wp_style_add_data( $theme_rtl['handle'], 'suffix', $min ); 
  202.  
  203. /** 
  204. * Enqueue the required JavaScript files 
  205. * @since 1.7.0 
  206. */ 
  207. public function enqueue_scripts() { 
  208. $min = bp_core_get_minified_asset_suffix(); 
  209.  
  210. // Locate the BP JS file. 
  211. $asset = $this->locate_asset_in_stack( "buddypress{$min}.js", 'js' ); 
  212.  
  213. // Enqueue the global JS, if found - AJAX will not work 
  214. // without it. 
  215. if ( isset( $asset['location'], $asset['handle'] ) ) { 
  216. wp_enqueue_script( $asset['handle'], $asset['location'], bp_core_get_js_dependencies(), $this->version ); 
  217.  
  218. /** 
  219. * Filters core JavaScript strings for internationalization before AJAX usage. 
  220. * @since 2.0.0 
  221. * @param array $value Array of key/value pairs for AJAX usage. 
  222. */ 
  223. $params = apply_filters( 'bp_core_get_js_strings', array( 
  224. 'accepted' => __( 'Accepted', 'buddypress' ),  
  225. 'close' => __( 'Close', 'buddypress' ),  
  226. 'comments' => __( 'comments', 'buddypress' ),  
  227. 'leave_group_confirm' => __( 'Are you sure you want to leave this group?', 'buddypress' ),  
  228. 'mark_as_fav' => __( 'Favorite', 'buddypress' ),  
  229. 'my_favs' => __( 'My Favorites', 'buddypress' ),  
  230. 'rejected' => __( 'Rejected', 'buddypress' ),  
  231. 'remove_fav' => __( 'Remove Favorite', 'buddypress' ),  
  232. 'show_all' => __( 'Show all', 'buddypress' ),  
  233. 'show_all_comments' => __( 'Show all comments for this thread', 'buddypress' ),  
  234. 'show_x_comments' => __( 'Show all comments (%d)', 'buddypress' ),  
  235. 'unsaved_changes' => __( 'Your profile has unsaved changes. If you leave the page, the changes will be lost.', 'buddypress' ),  
  236. 'view' => __( 'View', 'buddypress' ),  
  237. ) ); 
  238. wp_localize_script( $asset['handle'], 'BP_DTheme', $params ); 
  239.  
  240. // Maybe enqueue comment reply JS. 
  241. if ( is_singular() && bp_is_blog_page() && get_option( 'thread_comments' ) ) { 
  242. wp_enqueue_script( 'comment-reply' ); 
  243.  
  244. // Maybe enqueue password verify JS (register page or user settings page). 
  245. if ( bp_is_register_page() || ( function_exists( 'bp_is_user_settings_general' ) && bp_is_user_settings_general() ) ) { 
  246.  
  247. // Locate the Register Page JS file. 
  248. $asset = $this->locate_asset_in_stack( "password-verify{$min}.js", 'js', 'bp-legacy-password-verify' ); 
  249.  
  250. $dependencies = array_merge( bp_core_get_js_dependencies(), array( 
  251. 'password-strength-meter',  
  252. ) ); 
  253.  
  254. // Enqueue script. 
  255. wp_enqueue_script( $asset['handle'] . '-password-verify', $asset['location'], $dependencies, $this->version); 
  256.  
  257. // Star private messages. 
  258. if ( bp_is_active( 'messages', 'star' ) && bp_is_user_messages() ) { 
  259. wp_localize_script( $asset['handle'], 'BP_PM_Star', array( 
  260. 'strings' => array( 
  261. 'text_unstar' => __( 'Unstar', 'buddypress' ),  
  262. 'text_star' => __( 'Star', 'buddypress' ),  
  263. 'title_unstar' => __( 'Starred', 'buddypress' ),  
  264. 'title_star' => __( 'Not starred', 'buddypress' ),  
  265. 'title_unstar_thread' => __( 'Remove all starred messages in this thread', 'buddypress' ),  
  266. 'title_star_thread' => __( 'Star the first message in this thread', 'buddypress' ),  
  267. ),  
  268. 'is_single_thread' => (int) bp_is_messages_conversation(),  
  269. 'star_counter' => 0,  
  270. 'unstar_counter' => 0 
  271. ) ); 
  272.  
  273. /** 
  274. * Get the URL and handle of a web-accessible CSS or JS asset 
  275. * We provide two levels of customizability with respect to where CSS 
  276. * and JS files can be stored: (1) the child theme/parent theme/theme 
  277. * compat hierarchy, and (2) the "template stack" of /buddypress/css/,  
  278. * /community/css/, and /css/. In this way, CSS and JS assets can be 
  279. * overloaded, and default versions provided, in exactly the same way 
  280. * as corresponding PHP templates. 
  281. * We are duplicating some of the logic that is currently found in 
  282. * bp_locate_template() and the _template_stack() functions. Those 
  283. * functions were built with PHP templates in mind, and will require 
  284. * refactoring in order to provide "stack" functionality for assets 
  285. * that must be accessible both using file_exists() (the file path) 
  286. * and at a public URI. 
  287. * This method is marked private, with the understanding that the 
  288. * implementation is subject to change or removal in an upcoming 
  289. * release, in favor of a unified _template_stack() system. Plugin 
  290. * and theme authors should not attempt to use what follows. 
  291. * @since 1.8.0 
  292. * @param string $file A filename like buddypress.css. 
  293. * @param string $type Optional. Either "js" or "css" (the default). 
  294. * @param string $script_handle Optional. If set, used as the script name in `wp_enqueue_script`. 
  295. * @return array An array of data for the wp_enqueue_* function: 
  296. * 'handle' (eg 'bp-child-css') and a 'location' (the URI of the 
  297. * asset) 
  298. */ 
  299. private function locate_asset_in_stack( $file, $type = 'css', $script_handle = '' ) { 
  300. $locations = array(); 
  301.  
  302. // Ensure the assets can be located when running from /src/. 
  303. if ( defined( 'BP_SOURCE_SUBDIRECTORY' ) && BP_SOURCE_SUBDIRECTORY === 'src' ) { 
  304. $file = str_replace( '.min', '', $file ); 
  305.  
  306. // No need to check child if template == stylesheet. 
  307. if ( is_child_theme() ) { 
  308. $locations['bp-child'] = array( 
  309. 'dir' => get_stylesheet_directory(),  
  310. 'uri' => get_stylesheet_directory_uri(),  
  311. 'file' => str_replace( '.min', '', $file ),  
  312. ); 
  313.  
  314. $locations['bp-parent'] = array( 
  315. 'dir' => get_template_directory(),  
  316. 'uri' => get_template_directory_uri(),  
  317. 'file' => str_replace( '.min', '', $file ),  
  318. ); 
  319.  
  320. $locations['bp-legacy'] = array( 
  321. 'dir' => bp_get_theme_compat_dir(),  
  322. 'uri' => bp_get_theme_compat_url(),  
  323. 'file' => $file,  
  324. ); 
  325.  
  326. // Subdirectories within the top-level $locations directories. 
  327. $subdirs = array( 
  328. 'buddypress/' . $type,  
  329. 'community/' . $type,  
  330. $type,  
  331. ); 
  332.  
  333. $retval = array(); 
  334.  
  335. foreach ( $locations as $location_type => $location ) { 
  336. foreach ( $subdirs as $subdir ) { 
  337. if ( file_exists( trailingslashit( $location['dir'] ) . trailingslashit( $subdir ) . $location['file'] ) ) { 
  338. $retval['location'] = trailingslashit( $location['uri'] ) . trailingslashit( $subdir ) . $location['file']; 
  339. $retval['handle'] = ( $script_handle ) ? $script_handle : "{$location_type}-{$type}"; 
  340.  
  341. break 2; 
  342.  
  343. return $retval; 
  344.  
  345. /** 
  346. * Adds the no-js class to the body tag. 
  347. * This function ensures that the <body> element will have the 'no-js' class by default. If you're 
  348. * using JavaScript for some visual functionality in your theme, and you want to provide noscript 
  349. * support, apply those styles to body.no-js. 
  350. * The no-js class is removed by the JavaScript created in buddypress.js. 
  351. * @since 1.7.0 
  352. * @param array $classes Array of classes to append to body tag. 
  353. * @return array $classes 
  354. */ 
  355. public function add_nojs_body_class( $classes ) { 
  356. if ( ! in_array( 'no-js', $classes ) ) 
  357. $classes[] = 'no-js'; 
  358.  
  359. return array_unique( $classes ); 
  360.  
  361. /** 
  362. * Load localizations for topic script. 
  363. * These localizations require information that may not be loaded even by init. 
  364. * @since 1.7.0 
  365. */ 
  366. public function localize_scripts() { 
  367.  
  368. /** 
  369. * Outputs sitewide notices markup in the footer. 
  370. * @since 1.7.0 
  371. * @see https://buddypress.trac.wordpress.org/ticket/4802 
  372. */ 
  373. public function sitewide_notices() { 
  374. // Do not show notices if user is not logged in. 
  375. if ( ! is_user_logged_in() ) 
  376. return; 
  377.  
  378. // Add a class to determine if the admin bar is on or not. 
  379. $class = did_action( 'admin_bar_menu' ) ? 'admin-bar-on' : 'admin-bar-off'; 
  380.  
  381. echo '<div id="sitewide-notice" class="' . $class . '">'; 
  382. bp_message_get_notices(); 
  383. echo '</div>'; 
  384.  
  385. /** 
  386. * Add secondary avatar image to this activity stream's record, if supported. 
  387. * @since 1.7.0 
  388. * @param string $action The text of this activity. 
  389. * @param BP_Activity_Activity $activity Activity object. 
  390. * @return string 
  391. */ 
  392. function secondary_avatars( $action, $activity ) { 
  393. switch ( $activity->component ) { 
  394. case 'groups' : 
  395. case 'friends' : 
  396. // Only insert avatar if one exists. 
  397. if ( $secondary_avatar = bp_get_activity_secondary_avatar() ) { 
  398. $reverse_content = strrev( $action ); 
  399. $position = strpos( $reverse_content, 'a<' ); 
  400. $action = substr_replace( $action, $secondary_avatar, -$position - 2, 0 ); 
  401. break; 
  402.  
  403. return $action; 
  404.  
  405. /** 
  406. * Filter the default theme compatibility root template hierarchy, and prepend 
  407. * a page template to the front if it's set. 
  408. * @see https://buddypress.trac.wordpress.org/ticket/6065 
  409. * @since 2.2.0 
  410. * @param array $templates Array of templates. 
  411. * to use the defined page template for component's directory and its single items 
  412. * @return array 
  413. */ 
  414. public function theme_compat_page_templates( $templates = array() ) { 
  415.  
  416. /** 
  417. * Filters whether or not we are looking at a directory to determine if to return early. 
  418. * @since 2.2.0 
  419. * @param bool $value Whether or not we are viewing a directory. 
  420. */ 
  421. if ( true === (bool) apply_filters( 'bp_legacy_theme_compat_page_templates_directory_only', ! bp_is_directory() ) ) { 
  422. return $templates; 
  423.  
  424. // No page ID yet. 
  425. $page_id = 0; 
  426.  
  427. // Get the WordPress Page ID for the current view. 
  428. foreach ( (array) buddypress()->pages as $component => $bp_page ) { 
  429.  
  430. // Handles the majority of components. 
  431. if ( bp_is_current_component( $component ) ) { 
  432. $page_id = (int) $bp_page->id; 
  433.  
  434. // Stop if not on a user page. 
  435. if ( ! bp_is_user() && ! empty( $page_id ) ) { 
  436. break; 
  437.  
  438. // The Members component requires an explicit check due to overlapping components. 
  439. if ( bp_is_user() && ( 'members' === $component ) ) { 
  440. $page_id = (int) $bp_page->id; 
  441. break; 
  442.  
  443. // Bail if no directory page set. 
  444. if ( 0 === $page_id ) { 
  445. return $templates; 
  446.  
  447. // Check for page template. 
  448. $page_template = get_page_template_slug( $page_id ); 
  449.  
  450. // Add it to the beginning of the templates array so it takes precedence 
  451. // over the default hierarchy. 
  452. if ( ! empty( $page_template ) ) { 
  453.  
  454. /** 
  455. * Check for existence of template before adding it to template 
  456. * stack to avoid accidentally including an unintended file. 
  457. * @see: https://buddypress.trac.wordpress.org/ticket/6190 
  458. */ 
  459. if ( '' !== locate_template( $page_template ) ) { 
  460. array_unshift( $templates, $page_template ); 
  461.  
  462. return $templates;