[ Index ] |
PHP Cross Reference of BuddyPress |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Functions of BuddyPress's "Nouveau" template pack. 4 * 5 * @since 3.0.0 6 * @package BuddyPress 7 * @version 10.0.0 8 * 9 * @buddypress-template-pack { 10 * Template Pack ID: nouveau 11 * Template Pack Name: BP Nouveau 12 * Version: 1.0.0 13 * WP required version: 4.5.0 14 * BP required version: 3.0.0 15 * Description: A new template pack for BuddyPress! 16 * Text Domain: bp-nouveau 17 * Domain Path: /languages/ 18 * Author: The BuddyPress community 19 * Template Pack Supports: activity, blogs, friends, groups, messages, notifications, settings, xprofile 20 * }} 21 */ 22 23 // Exit if accessed directly. 24 defined( 'ABSPATH' ) || exit; 25 26 /** Theme Setup ***************************************************************/ 27 28 /** 29 * Loads BuddyPress Nouveau Template pack functionality. 30 * 31 * See @link BP_Theme_Compat() for more. 32 * 33 * @since 3.0.0 34 */ 35 class BP_Nouveau extends BP_Theme_Compat { 36 37 /** 38 * Instance of this class. 39 * 40 * @var BP_Nouveau|null 41 */ 42 protected static $instance = null; 43 44 /** 45 * Return the instance of this class. 46 * 47 * @since 3.0.0 48 * 49 * @return BP_Nouveau 50 */ 51 public static function get_instance() { 52 if ( null === self::$instance ) { 53 self::$instance = new self; 54 } 55 56 return self::$instance; 57 } 58 59 /** 60 * The BP Nouveau constructor. 61 * 62 * @since 3.0.0 63 */ 64 public function __construct() { 65 parent::start(); 66 67 $this->includes(); 68 $this->setup_support(); 69 } 70 71 /** 72 * BP Nouveau global variables. 73 * 74 * @since 3.0.0 75 */ 76 protected function setup_globals() { 77 $bp = buddypress(); 78 79 foreach ( $bp->theme_compat->packages['nouveau'] as $property => $value ) { 80 $this->{$property} = $value; 81 } 82 83 $this->includes_dir = trailingslashit( $this->dir ) . 'includes/'; 84 $this->directory_nav = new BP_Core_Nav( bp_get_root_blog_id() ); 85 } 86 87 /** 88 * Includes! 89 * 90 * @since 3.0.0 91 */ 92 protected function includes() { 93 require $this->includes_dir . 'functions.php'; 94 require $this->includes_dir . 'classes.php'; 95 require $this->includes_dir . 'template-tags.php'; 96 97 // Test suite requires the AJAX functions early. 98 if ( function_exists( 'tests_add_filter' ) ) { 99 require $this->includes_dir . 'ajax.php'; 100 101 // Load AJAX code only on AJAX requests. 102 } else { 103 add_action( 'admin_init', function() { 104 if ( defined( 'DOING_AJAX' ) && true === DOING_AJAX ) { 105 require bp_nouveau()->includes_dir . 'ajax.php'; 106 } 107 }, 0 ); 108 } 109 110 add_action( 'bp_customize_register', function() { 111 if ( bp_is_root_blog() && current_user_can( 'customize' ) ) { 112 require bp_nouveau()->includes_dir . 'customizer.php'; 113 } 114 }, 0 ); 115 116 foreach ( bp_core_get_packaged_component_ids() as $component ) { 117 $component_loader = trailingslashit( $this->includes_dir ) . $component . '/loader.php'; 118 119 if ( ! bp_is_active( $component ) || ! file_exists( $component_loader ) ) { 120 continue; 121 } 122 123 require( $component_loader ); 124 } 125 126 /** 127 * Fires after all of the BuddyPress Nouveau includes have been loaded. Passed by reference. 128 * 129 * @since 3.0.0 130 * 131 * @param BP_Nouveau $value Current BP_Nouveau instance. 132 */ 133 do_action_ref_array( 'bp_nouveau_includes', array( &$this ) ); 134 } 135 136 /** 137 * Setup the Template Pack features support. 138 * 139 * @since 3.0.0 140 */ 141 protected function setup_support() { 142 $width = 1300; 143 $top_offset = 150; 144 145 /** This filter is documented in bp-core/bp-core-avatars.php. */ 146 $avatar_height = apply_filters( 'bp_core_avatar_full_height', $top_offset ); 147 148 if ( $avatar_height > $top_offset ) { 149 $top_offset = $avatar_height; 150 } 151 152 bp_set_theme_compat_feature( $this->id, array( 153 'name' => 'cover_image', 154 'settings' => array( 155 'components' => array( 'members', 'groups' ), 156 'width' => $width, 157 'height' => $top_offset + round( $avatar_height / 2 ), 158 'callback' => 'bp_nouveau_theme_cover_image', 159 'theme_handle' => 'bp-nouveau', 160 ), 161 ) ); 162 } 163 164 /** 165 * Setup the Template Pack common actions. 166 * 167 * @since 3.0.0 168 */ 169 protected function setup_actions() { 170 // Filter BuddyPress template hierarchy and look for page templates. 171 add_filter( 'bp_get_buddypress_template', array( $this, 'theme_compat_page_templates' ), 10, 1 ); 172 173 // Add our "buddypress" div wrapper to theme compat template parts. 174 add_filter( 'bp_replace_the_content', array( $this, 'theme_compat_wrapper' ), 999 ); 175 176 // We need to neutralize the BuddyPress core "bp_core_render_message()" once it has been added. 177 add_action( 'bp_actions', array( $this, 'neutralize_core_template_notices' ), 6 ); 178 179 // Scripts & Styles. 180 $registration_params = array( 181 'hook' => 'bp_enqueue_scripts', 182 'priority' => 2, 183 ); 184 185 /* 186 * The WordPress Full Site Editing feature needs Scripts 187 * and Styles to be registered earlier. 188 */ 189 if ( current_theme_supports( 'block-templates' ) ) { 190 $registration_params['hook'] = 'bp_init'; 191 $registration_params['priority'] = 20; 192 } 193 194 // Register theme JS. 195 add_action( $registration_params['hook'], array( $this, 'register_scripts' ), $registration_params['priority'] ); 196 197 // Enqueue theme CSS. 198 add_action( 'bp_enqueue_scripts', array( $this, 'enqueue_styles' ) ); 199 200 // Enqueue theme JS. 201 add_action( 'bp_enqueue_scripts', array( $this, 'enqueue_scripts' ) ); 202 203 // Enqueue theme script localization. 204 add_filter( 'bp_enqueue_scripts', array( $this, 'localize_scripts' ) ); 205 remove_action( 'bp_enqueue_scripts', 'bp_core_confirmation_js' ); 206 207 // Body no-js class. 208 add_filter( 'body_class', array( $this, 'add_nojs_body_class' ), 20, 1 ); 209 210 // Ajax querystring. 211 add_filter( 'bp_ajax_querystring', 'bp_nouveau_ajax_querystring', 10, 2 ); 212 213 // Register directory nav items. 214 add_action( 'bp_screens', array( $this, 'setup_directory_nav' ), 15 ); 215 216 // Register the Default front pages Dynamic Sidebars. 217 add_action( 'widgets_init', 'bp_nouveau_register_sidebars', 11 ); 218 219 // Register the Primary Object nav widget. 220 if ( bp_core_retain_legacy_widgets() ) { 221 add_action( 'bp_widgets_init', array( 'BP_Nouveau_Object_Nav_Widget', 'register_widget' ) ); 222 } 223 224 // Set the BP Uri for the Ajax customizer preview. 225 add_filter( 'bp_uri', array( $this, 'customizer_set_uri' ), 10, 1 ); 226 227 // Modify "registration disabled" and welcome message if invitations are enabled. 228 add_action( 'bp_nouveau_feedback_messages', array( $this, 'filter_registration_messages' ), 99 ); 229 230 /** Override **********************************************************/ 231 232 /** 233 * Fires after all of the BuddyPress theme compat actions have been added. 234 * 235 * @since 3.0.0 236 * 237 * @param BP_Nouveau $this Current BP_Nouveau instance. 238 */ 239 do_action_ref_array( 'bp_theme_compat_actions', array( &$this ) ); 240 } 241 242 /** 243 * Enqueue the template pack css files 244 * 245 * @since 3.0.0 246 */ 247 public function enqueue_styles() { 248 $min = bp_core_get_minified_asset_suffix(); 249 $rtl = ''; 250 251 if ( is_rtl() ) { 252 $rtl = '-rtl'; 253 } 254 255 /** 256 * Filters the BuddyPress Nouveau CSS dependencies. 257 * 258 * @since 3.0.0 259 * 260 * @param array $value Array of style dependencies. Default Dashicons. 261 */ 262 $css_dependencies = apply_filters( 'bp_nouveau_css_dependencies', array( 'dashicons' ) ); 263 264 /** 265 * Filters the styles to enqueue for BuddyPress Nouveau. 266 * 267 * This filter provides a multidimensional array that will map to arguments used for wp_enqueue_style(). 268 * The primary index should have the stylesheet handle to use, and be assigned an array that has indexes for 269 * file location, dependencies, and version. 270 * 271 * @since 3.0.0 272 * 273 * @param array $value Array of styles to enqueue. 274 */ 275 $styles = apply_filters( 'bp_nouveau_enqueue_styles', array( 276 'bp-nouveau' => array( 277 'file' => 'css/buddypress%1$s%2$s.css', 'dependencies' => $css_dependencies, 'version' => $this->version, 278 ), 279 ) ); 280 281 if ( $styles ) { 282 283 foreach ( $styles as $handle => $style ) { 284 if ( ! isset( $style['file'] ) ) { 285 continue; 286 } 287 288 $file = sprintf( $style['file'], $rtl, $min ); 289 290 // Locate the asset if needed. 291 if ( false === strpos( $style['file'], '://' ) ) { 292 $asset = bp_locate_template_asset( $file ); 293 294 if ( empty( $asset['uri'] ) || false === strpos( $asset['uri'], '://' ) ) { 295 continue; 296 } 297 298 $file = $asset['uri']; 299 } 300 301 $data = bp_parse_args( 302 $style, 303 array( 304 'dependencies' => array(), 305 'version' => $this->version, 306 'type' => 'screen', 307 ), 308 'nouveau_enqueue_styles' 309 ); 310 311 wp_enqueue_style( $handle, $file, $data['dependencies'], $data['version'], $data['type'] ); 312 313 if ( $min ) { 314 wp_style_add_data( $handle, 'suffix', $min ); 315 } 316 } 317 } 318 319 // Compatibility stylesheets for specific themes. 320 $theme = get_template(); 321 $companion_stylesheet = bp_locate_template_asset( sprintf( 'css/%1$s%2$s.css', $theme, $min ) ); 322 $companion_handle = 'bp-' . $theme; 323 324 if ( ! is_rtl() && isset( $companion_stylesheet['uri'] ) && $companion_stylesheet['uri'] ) { 325 wp_enqueue_style( $companion_handle, $companion_stylesheet['uri'], array(), $this->version, 'screen' ); 326 327 if ( $min ) { 328 wp_style_add_data( $companion_handle, 'suffix', $min ); 329 } 330 } 331 332 // Compatibility stylesheet for specific themes, RTL-version. 333 if ( is_rtl() ) { 334 $rtl_companion_stylesheet = bp_locate_template_asset( sprintf( 'css/%1$s-rtl%2$s.css', $theme, $min ) ); 335 336 if ( isset( $rtl_companion_stylesheet['uri'] ) ) { 337 $companion_handle .= '-rtl'; 338 wp_enqueue_style( $companion_handle, $rtl_companion_stylesheet['uri'], array(), $this->version, 'screen' ); 339 340 if ( $min ) { 341 wp_style_add_data( $companion_handle, 'suffix', $min ); 342 } 343 } 344 } 345 } 346 347 /** 348 * Register Template Pack JavaScript files 349 * 350 * @since 3.0.0 351 */ 352 public function register_scripts() { 353 $min = bp_core_get_minified_asset_suffix(); 354 $dependencies = bp_core_get_js_dependencies(); 355 $bp_confirm = array_search( 'bp-confirm', $dependencies ); 356 357 unset( $dependencies[ $bp_confirm ] ); 358 359 /** 360 * Filters the scripts to enqueue for BuddyPress Nouveau. 361 * 362 * This filter provides a multidimensional array that will map to arguments used for wp_register_script(). 363 * The primary index should have the script handle to use, and be assigned an array that has indexes for 364 * file location, dependencies, version and if it should load in the footer or not. 365 * 366 * @since 3.0.0 367 * 368 * @param array $value Array of scripts to register. 369 */ 370 $scripts = apply_filters( 371 'bp_nouveau_register_scripts', 372 array( 373 'bp-nouveau' => array( 374 'file' => 'js/buddypress-nouveau%s.js', 375 'dependencies' => $dependencies, 376 'version' => $this->version, 377 'footer' => true, 378 ), 379 ) 380 ); 381 382 // Bail if no scripts. 383 if ( empty( $scripts ) ) { 384 return; 385 } 386 387 foreach ( $scripts as $handle => $script ) { 388 if ( ! isset( $script['file'] ) ) { 389 continue; 390 } 391 392 $file = sprintf( $script['file'], $min ); 393 394 // Locate the asset if needed. 395 if ( false === strpos( $script['file'], '://' ) ) { 396 $asset = bp_locate_template_asset( $file ); 397 398 if ( empty( $asset['uri'] ) || false === strpos( $asset['uri'], '://' ) ) { 399 continue; 400 } 401 402 $file = $asset['uri']; 403 } 404 405 $data = bp_parse_args( 406 $script, 407 array( 408 'dependencies' => array(), 409 'version' => $this->version, 410 'footer' => false, 411 ), 412 'nouveau_register_scripts' 413 ); 414 415 wp_register_script( $handle, $file, $data['dependencies'], $data['version'], $data['footer'] ); 416 } 417 } 418 419 /** 420 * Enqueue the required JavaScript files 421 * 422 * @since 3.0.0 423 */ 424 public function enqueue_scripts() { 425 wp_enqueue_script( 'bp-nouveau' ); 426 427 if ( bp_is_register_page() || bp_is_user_settings_general() ) { 428 wp_enqueue_script( 'user-profile' ); 429 } 430 431 if ( is_singular() && bp_is_blog_page() && get_option( 'thread_comments' ) ) { 432 wp_enqueue_script( 'comment-reply' ); 433 } 434 435 /** 436 * Fires after all of the BuddyPress Nouveau scripts have been enqueued. 437 * 438 * @since 3.0.0 439 */ 440 do_action( 'bp_nouveau_enqueue_scripts' ); 441 } 442 443 /** 444 * Adds the no-js class to the body tag. 445 * 446 * This function ensures that the <body> element will have the 'no-js' class by default. If you're 447 * using JavaScript for some visual functionality in your theme, and you want to provide noscript 448 * support, apply those styles to body.no-js. 449 * 450 * The no-js class is removed by the JavaScript created in buddypress.js. 451 * 452 * @since 3.0.0 453 * 454 * @param array $classes Array of classes to append to body tag. 455 * 456 * @return array $classes 457 */ 458 public function add_nojs_body_class( $classes ) { 459 $classes[] = 'no-js'; 460 return array_unique( $classes ); 461 } 462 463 /** 464 * Load localizations for topic script. 465 * 466 * These localizations require information that may not be loaded even by init. 467 * 468 * @since 3.0.0 469 */ 470 public function localize_scripts() { 471 $params = array( 472 'ajaxurl' => bp_core_ajax_url(), 473 'confirm' => __( 'Are you sure?', 'buddypress' ), 474 475 /* translators: %s: number of activity comments */ 476 'show_x_comments' => __( 'Show all %d comments', 'buddypress' ), 477 'unsaved_changes' => __( 'Your profile has unsaved changes. If you leave the page, the changes will be lost.', 'buddypress' ), 478 'object_nav_parent' => '#buddypress', 479 ); 480 481 // If the Object/Item nav are in the sidebar. 482 if ( bp_nouveau_is_object_nav_in_sidebar() ) { 483 $params['object_nav_parent'] = '.buddypress_object_nav'; 484 } 485 486 /** 487 * Filters the supported BuddyPress Nouveau components. 488 * 489 * @since 3.0.0 490 * 491 * @param array $value Array of supported components. 492 */ 493 $supported_objects = (array) apply_filters( 'bp_nouveau_supported_components', bp_core_get_packaged_component_ids() ); 494 $object_nonces = array(); 495 496 foreach ( $supported_objects as $key_object => $object ) { 497 if ( ! bp_is_active( $object ) || 'forums' === $object ) { 498 unset( $supported_objects[ $key_object ] ); 499 continue; 500 } 501 502 $object_nonces[ $object ] = wp_create_nonce( 'bp_nouveau_' . $object ); 503 } 504 505 // Groups require some additional objects. 506 if ( bp_is_active( 'groups' ) ) { 507 $supported_objects = array_merge( $supported_objects, array( 'group_members', 'group_requests' ) ); 508 } 509 510 // Add components & nonces. 511 $params['objects'] = $supported_objects; 512 $params['nonces'] = $object_nonces; 513 514 // Used to transport the settings inside the Ajax requests. 515 if ( is_customize_preview() ) { 516 $params['customizer_settings'] = bp_nouveau_get_temporary_setting( 'any' ); 517 } 518 519 $required_password_strength = bp_members_user_pass_required_strength(); 520 if ( $required_password_strength ) { 521 $params['bpPasswordVerify'] = array( 522 'tooWeakPasswordWarning' => __( 'Your password is too weak, please use a stronger password.', 'buddypress' ), 523 'requiredPassStrength' => bp_members_user_pass_required_strength(), 524 ); 525 } 526 527 /** 528 * Filters core JavaScript strings for internationalization before AJAX usage. 529 * 530 * @since 3.0.0 531 * 532 * @param array $params Array of key/value pairs for AJAX usage. 533 */ 534 wp_localize_script( 'bp-nouveau', 'BP_Nouveau', apply_filters( 'bp_core_get_js_strings', $params ) ); 535 } 536 537 /** 538 * Filter the default theme compatibility root template hierarchy, and prepend 539 * a page template to the front if it's set. 540 * 541 * @see https://buddypress.trac.wordpress.org/ticket/6065 542 * 543 * @since 3.0.0 544 * 545 * @param array $templates Array of templates. 546 * 547 * @return array 548 */ 549 public function theme_compat_page_templates( $templates = array() ) { 550 /** 551 * Filters whether or not we are looking at a directory to determine if to return early. 552 * 553 * @since 3.0.0 554 * 555 * @param bool $value Whether or not we are viewing a directory. 556 */ 557 if ( true === (bool) apply_filters( 'bp_nouveau_theme_compat_page_templates_directory_only', ! bp_is_directory() ) ) { 558 return $templates; 559 } 560 561 // No page ID yet. 562 $page_id = 0; 563 564 // Get the WordPress Page ID for the current view. 565 foreach ( (array) buddypress()->pages as $component => $bp_page ) { 566 567 // Handles the majority of components. 568 if ( bp_is_current_component( $component ) ) { 569 $page_id = (int) $bp_page->id; 570 } 571 572 // Stop if not on a user page. 573 if ( ! bp_is_user() && ! empty( $page_id ) ) { 574 break; 575 } 576 577 // The Members component requires an explicit check due to overlapping components. 578 if ( bp_is_user() && ( 'members' === $component ) ) { 579 $page_id = (int) $bp_page->id; 580 break; 581 } 582 } 583 584 // Bail if no directory page set. 585 if ( 0 === $page_id ) { 586 return $templates; 587 } 588 589 // Check for page template. 590 $page_template = get_page_template_slug( $page_id ); 591 592 // Add it to the beginning of the templates array so it takes precedence over the default hierarchy. 593 if ( ! empty( $page_template ) ) { 594 595 /** 596 * Check for existence of template before adding it to template 597 * stack to avoid accidentally including an unintended file. 598 * 599 * @see https://buddypress.trac.wordpress.org/ticket/6190 600 */ 601 if ( '' !== locate_template( $page_template ) ) { 602 array_unshift( $templates, $page_template ); 603 } 604 } 605 606 return $templates; 607 } 608 609 /** 610 * Add our special 'buddypress' div wrapper to the theme compat template part. 611 * 612 * @since 3.0.0 613 * 614 * @see bp_buffer_template_part() 615 * 616 * @param string $retval Current template part contents. 617 * 618 * @return string 619 */ 620 public function theme_compat_wrapper( $retval ) { 621 if ( false !== strpos( $retval, '<div id="buddypress"' ) ) { 622 return $retval; 623 } 624 625 // Add our 'buddypress' div wrapper. 626 return sprintf( 627 '<div id="buddypress" class="%1$s">%2$s</div><!-- #buddypress -->%3$s', 628 esc_attr( bp_nouveau_get_container_classes() ), 629 $retval, // Constructed HTML. 630 "\n" 631 ); 632 } 633 634 /** 635 * Define the directory nav items 636 * 637 * @since 3.0.0 638 */ 639 public function setup_directory_nav() { 640 $nav_items = array(); 641 642 if ( bp_is_members_directory() ) { 643 $nav_items = bp_nouveau_get_members_directory_nav_items(); 644 } elseif ( bp_is_activity_directory() ) { 645 $nav_items = bp_nouveau_get_activity_directory_nav_items(); 646 } elseif ( bp_is_groups_directory() ) { 647 $nav_items = bp_nouveau_get_groups_directory_nav_items(); 648 } elseif ( bp_is_blogs_directory() ) { 649 $nav_items = bp_nouveau_get_blogs_directory_nav_items(); 650 } 651 652 if ( empty( $nav_items ) ) { 653 return; 654 } 655 656 foreach ( $nav_items as $nav_item ) { 657 if ( empty( $nav_item['component'] ) || $nav_item['component'] !== bp_current_component() ) { 658 continue; 659 } 660 661 // Define the primary nav for the current component's directory. 662 $this->directory_nav->add_nav( $nav_item ); 663 } 664 } 665 666 /** 667 * We'll handle template notices from BP Nouveau. 668 * 669 * @since 3.0.0 670 */ 671 public function neutralize_core_template_notices() { 672 remove_action( 'template_notices', 'bp_core_render_message' ); 673 } 674 675 /** 676 * Set the BP Uri for the customizer in case of Ajax requests. 677 * 678 * @since 3.0.0 679 * 680 * @param string $path The BP Uri. 681 * @return string The BP Uri. 682 */ 683 public function customizer_set_uri( $path ) { 684 if ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX ) { 685 return $path; 686 } 687 688 $uri = parse_url( $path ); 689 690 if ( false === strpos( $uri['path'], 'customize.php' ) ) { 691 return $path; 692 } else { 693 $vars = bp_parse_args( 694 $uri['query'], 695 array(), 696 'customizer_set_uri' 697 ); 698 699 if ( ! empty( $vars['url'] ) ) { 700 $path = str_replace( get_site_url(), '', urldecode( $vars['url'] ) ); 701 } 702 } 703 704 return $path; 705 } 706 707 /** 708 * Modify "registration disabled" message in Nouveau template pack. 709 * Modify welcome message in Nouveau template pack. 710 * 711 * @since 8.0.0 712 * 713 * @param array $messages The list of feedback messages. 714 * 715 * @return array $messages 716 */ 717 public function filter_registration_messages( $messages ) { 718 // Change the "registration is disabled" message. 719 $disallowed_message = bp_members_invitations_get_modified_registration_disabled_message(); 720 if ( $disallowed_message ) { 721 $messages['registration-disabled']['message'] = $disallowed_message; 722 } 723 724 // Add information about invitations to the welcome block. 725 $welcome_message = bp_members_invitations_get_registration_welcome_message(); 726 if ( $welcome_message ) { 727 $messages['request-details']['message'] = $welcome_message . ' ' . $messages['request-details']['message']; 728 } 729 730 return $messages; 731 } 732 } 733 734 /** 735 * Get a unique instance of BP Nouveau 736 * 737 * @since 3.0.0 738 * 739 * @return BP_Nouveau the main instance of the class 740 */ 741 function bp_nouveau() { 742 return BP_Nouveau::get_instance(); 743 } 744 745 /** 746 * Launch BP Nouveau! 747 */ 748 bp_nouveau();
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Nov 21 01:00:57 2024 | Cross-referenced by PHPXref 0.7.1 |