Skip to:
Content

BuddyPress.org

Changeset 13455


Ignore:
Timestamp:
04/20/2023 02:30:11 AM (14 months ago)
Author:
imath
Message:

Start implementing parse_query() methods for directory components

First concerned commponents are: Activity, Blogs & Members.

  • Remove the notice used to force pretty permalinks
  • Use plain links to test parse_query() methods are rightly setting BuddyPress URI globals
  • Introduce some helper functions used during the BP Rewrites API parsing process :
    • bp_is_directory_homepage() is checking if a BP Directory is used as the site's homepage
    • bp_rewrites_get_custom_slug_rewrite_id() finds a Rewrite ID out of a custom slug.
    • bp_rewrites_get_member_data() returns the field to use to get the user by.
    • bp_reset_query() makes it possible to parse again a request in specific cases (eg: root profiles)

Props r-a-y, johnjamesjacoby, boonebgorges

Closes https://github.com/buddypress/buddypress/pull/87
See #4954

Location:
trunk/src
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/bp-activity/classes/class-bp-activity-component.php

    r13450 r13455  
    498498
    499499    /**
     500     * Parse the WP_Query and eventually display the component's directory or single item.
     501     *
     502     * @since 12.0.0
     503     *
     504     * @param WP_Query $query Required. See BP_Component::parse_query() for
     505     *                        description.
     506     */
     507    public function parse_query( $query ) {
     508        if ( bp_is_directory_homepage( $this->id ) ) {
     509            $query->set( $this->rewrite_ids['directory'], 1 );
     510        }
     511
     512        if ( 1 === (int) $query->get( $this->rewrite_ids['directory'] ) ) {
     513            $bp = buddypress();
     514
     515            // Set the Activity component as current.
     516            $bp->current_component = 'activity';
     517
     518            $current_action = $query->get( $this->rewrite_ids['single_item_action'] );
     519            if ( $current_action ) {
     520                $bp->current_action = $current_action;
     521            }
     522
     523            $action_variables = $query->get( $this->rewrite_ids['single_item_action_variables'] );
     524            if ( $action_variables ) {
     525                if ( ! is_array( $action_variables ) ) {
     526                    $bp->action_variables = explode( '/', ltrim( $action_variables, '/' ) );
     527                } else {
     528                    $bp->action_variables = $action_variables;
     529                }
     530            }
     531
     532            // Set the BuddyPress queried object.
     533            if ( isset( $bp->pages->activity->id ) ) {
     534                $query->queried_object    = get_post( $bp->pages->activity->id );
     535                $query->queried_object_id = $query->queried_object->ID;
     536            }
     537        }
     538
     539        parent::parse_query( $query );
     540    }
     541
     542    /**
    500543     * Init the BP REST API.
    501544     *
  • trunk/src/bp-blogs/classes/class-bp-blogs-component.php

    r13450 r13455  
    435435
    436436        parent::add_rewrite_rules( $rewrite_rules );
     437    }
     438
     439    /**
     440     * Parse the WP_Query and eventually display the component's directory or single item.
     441     *
     442     * @since 12.0.0
     443     *
     444     * @param WP_Query $query Required. See BP_Component::parse_query() for
     445     *                        description.
     446     */
     447    public function parse_query( $query ) {
     448        if ( ! is_multisite() ) {
     449            return parent::parse_query( $query );
     450        }
     451
     452        // Get the BuddyPress main instance.
     453        $bp = buddypress();
     454
     455        if ( bp_is_directory_homepage( $this->id ) ) {
     456            $query->set( $this->rewrite_ids['directory'], 1 );
     457        }
     458
     459        if ( 1 === (int) $query->get( $this->rewrite_ids['directory'] ) ) {
     460            $bp->current_component = 'blogs';
     461
     462            $current_action = $query->get( $this->rewrite_ids['single_item_action'] );
     463            if ( $current_action ) {
     464                $bp->current_action = $current_action;
     465            }
     466
     467            $action_variables = $query->get( $this->rewrite_ids['single_item_action_variables'] );
     468            if ( $action_variables ) {
     469                if ( ! is_array( $action_variables ) ) {
     470                    $bp->action_variables = explode( '/', ltrim( $action_variables, '/' ) );
     471                } else {
     472                    $bp->action_variables = $action_variables;
     473                }
     474            }
     475
     476            // Set the BuddyPress queried object.
     477            if ( isset( $bp->pages->blogs->id ) ) {
     478                $query->queried_object    = get_post( $bp->pages->blogs->id );
     479                $query->queried_object_id = $query->queried_object->ID;
     480            }
     481        }
     482
     483        parent::parse_query( $query );
    437484    }
    438485
  • trunk/src/bp-core/admin/bp-core-admin-functions.php

    r13450 r13455  
    205205 *
    206206 * On every Dashboard page, this function checks the following:
    207  *   - that pretty permalinks are enabled.
    208207 *   - that every BP component that needs a WP page for a directory has one.
    209208 *   - that no WP page has multiple BP components associated with it.
     
    250249            bp_blogs_record_existing_blogs();
    251250        }
    252     }
    253 
    254     // Add notice if no rewrite rules are enabled.
    255     if ( empty( $wp_rewrite->permalink_structure ) ) {
    256         bp_core_add_admin_notice(
    257             sprintf(
    258                 // Translators: %s is the url to the permalink settings.
    259                 __( '<strong>BuddyPress is almost ready</strong>. You must <a href="%s">update your permalink structure</a> to something other than the default for it to work.', 'buddypress' ),
    260                 admin_url( 'options-permalink.php' )
    261             ),
    262             'error'
    263         );
    264251    }
    265252
  • trunk/src/bp-core/bp-core-functions.php

    r13449 r13455  
    956956}
    957957add_filter( 'wp_unique_post_slug', 'bp_core_set_unique_directory_page_slug', 10, 6 );
     958
     959/**
     960 * Checks if a component's directory is set as the site's homepage.
     961 *
     962 * @since 12.0.0
     963 *
     964 * @param string   $component The component ID.
     965 * @return boolean            True if a component's directory is set as the site's homepage.
     966 *                            False otherwise.
     967 */
     968function bp_is_directory_homepage( $component = '' ) {
     969    $is_directory_homepage = false;
     970    $is_page_on_front      = 'page' === get_option( 'show_on_front', 'posts' );
     971    $page_id_on_front      = get_option( 'page_on_front', 0 );
     972    $directory_pages       = bp_core_get_directory_pages();
     973
     974    if ( $is_page_on_front && isset( $directory_pages->{$component} ) && (int) $page_id_on_front === (int) $directory_pages->{$component}->id ) {
     975        $is_directory_homepage = true;
     976    }
     977
     978    return $is_directory_homepage;
     979}
    958980
    959981/**
  • trunk/src/bp-core/bp-core-rewrites.php

    r13452 r13455  
    116116
    117117    return $slug;
     118}
     119
     120/**
     121 * Returns the rewrite ID of a customized slug.
     122 *
     123 * @since 12.0.0
     124 *
     125 * @param string $component_id The component ID (eg: `activity` for the BP Activity component).
     126 * @param string $slug         The customized slug.
     127 * @param string $context      The context for the customized slug, useful when the same slug is used
     128 *                             for more than one rewrite ID of the same component.
     129 * @return string              The rewrite ID matching the customized slug.
     130 */
     131function bp_rewrites_get_custom_slug_rewrite_id( $component_id = '', $slug = '', $context = '' ) {
     132    $directory_pages = bp_core_get_directory_pages();
     133
     134    if ( ! isset( $directory_pages->{$component_id}->custom_slugs ) || ! $slug ) {
     135        return null;
     136    }
     137
     138    $custom_slugs = (array) $directory_pages->{$component_id}->custom_slugs;
     139    $rewrite_ids  = array_keys( $custom_slugs, $slug, true );
     140
     141    if ( 1 < count( $rewrite_ids ) && isset( $context ) && $context ) {
     142        foreach ( $rewrite_ids as $rewrite_id_key => $rewrite_id ) {
     143            if ( false !== strpos( $rewrite_id, $context ) ) {
     144                continue;
     145            }
     146
     147            unset( $rewrite_ids[ $rewrite_id_key ] );
     148        }
     149    }
     150
     151    // Always return the first match.
     152    return reset( $rewrite_ids );
    118153}
    119154
     
    284319    return apply_filters( 'bp_rewrites_get_root_url', $url );
    285320}
     321
     322/**
     323 * Get needed data to find a member single item from the requested URL.
     324 *
     325 * @since 12.0.0
     326 *
     327 * @param string $request The request used during parsing.
     328 * @return array          Data to use to find a member single item from the request.
     329 */
     330function bp_rewrites_get_member_data( $request = '' ) {
     331    $member_data = array( 'field' => 'slug' );
     332
     333    if ( bp_is_username_compatibility_mode() ) {
     334        $member_data = array( 'field' => 'login' );
     335    }
     336
     337    if ( bp_core_enable_root_profiles() ) {
     338        if ( ! $request ) {
     339            $request = $GLOBALS['wp']->request;
     340        }
     341
     342        $request_chunks = explode( '/', ltrim( $request, '/' ) );
     343        $member_chunk   = reset( $request_chunks );
     344
     345        // Try to get an existing member to eventually reset the WP Query.
     346        $member_data['object'] = get_user_by( $member_data['field'], $member_chunk );
     347    }
     348
     349    return $member_data;
     350}
  • trunk/src/bp-core/bp-core-template-loader.php

    r13350 r13455  
    579579
    580580/**
     581 * Resets the query to fit our permalink structure if needed.
     582 *
     583 * This is used for specific cases such as Root Member's profile.
     584 *
     585 * @since 12.0.0
     586 *
     587 * @param string   $bp_request A specific BuddyPress request.
     588 * @param WP_Query $query The WordPress query object.
     589 * @return true
     590 */
     591function bp_reset_query( $bp_request = '', WP_Query $query = null ) {
     592    global $wp;
     593
     594    // Get BuddyPress main instance.
     595    $bp = buddypress();
     596
     597    // Back up request uri.
     598    $reset_server_request_uri = '';
     599    if ( isset( $_SERVER['REQUEST_URI'] ) ) {
     600        $reset_server_request_uri = esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) );
     601    }
     602
     603    // Temporarly override the request uri.
     604    if ( isset( $wp->request ) ) {
     605        $_SERVER['REQUEST_URI'] = str_replace( $wp->request, $bp_request, $reset_server_request_uri );
     606
     607        // Reparse request.
     608        $wp->parse_request();
     609
     610        // Reparse query.
     611        bp_remove_all_filters( 'parse_query' );
     612        $query->parse_query( $wp->query_vars );
     613        bp_restore_all_filters( 'parse_query' );
     614    }
     615
     616    // Restore request uri.
     617    $_SERVER['REQUEST_URI'] = $reset_server_request_uri;
     618
     619    // The query is reset.
     620    return true;
     621}
     622
     623/**
    581624 * Possibly intercept the template being loaded.
    582625 *
  • trunk/src/bp-core/classes/class-bp-component.php

    r13450 r13455  
    578578
    579579        // Allow components to parse the main query.
    580         add_action( 'bp_parse_query',            array( $this, 'parse_query'            ), 10 );
     580        if ( ! bp_has_pretty_urls() ) {
     581            /**
     582             * Only fire this hook when pretty links are disabled.
     583             *
     584             * @todo Remove once BP Rewrites merge process is ended.
     585             */
     586            add_action( 'bp_parse_query',  array( $this, 'parse_query' ), 10 );
     587        }
    581588
    582589        // Generate rewrite rules.
  • trunk/src/bp-members/classes/class-bp-members-component.php

    r13450 r13455  
    759759
    760760    /**
     761     * Parse the WP_Query and eventually display the component's directory or single item.
     762     *
     763     * @since 12.0.0
     764     *
     765     * @param WP_Query $query Required. See BP_Component::parse_query() for
     766     *                        description.
     767     */
     768    public function parse_query( $query ) {
     769        // Init the current member and member type.
     770        $member      = false;
     771        $member_type = false;
     772        $member_data = bp_rewrites_get_member_data();
     773
     774        if ( isset( $member_data['object'] ) && $member_data['object'] ) {
     775            bp_reset_query( trailingslashit( $this->root_slug ) . $GLOBALS['wp']->request, $query );
     776            $member = $member_data['object'];
     777
     778            // Make sure the Member's screen is fired.
     779            add_action( 'bp_screens', 'bp_members_screen_display_profile', 3 );
     780        }
     781
     782        if ( bp_is_directory_homepage( $this->id ) ) {
     783            $query->set( $this->rewrite_ids['directory'], 1 );
     784        }
     785
     786        // Which component are we displaying?
     787        $is_members_component  = 1 === (int) $query->get( $this->rewrite_ids['directory'] );
     788        $is_register_component = 1 === (int) $query->get( $this->rewrite_ids['member_register'] );
     789        $is_activate_component = 1 === (int) $query->get( $this->rewrite_ids['member_activate'] );
     790
     791        // Get BuddyPress main instance.
     792        $bp = buddypress();
     793
     794        if ( $is_members_component ) {
     795            $bp->current_component = 'members';
     796            $member_slug           = $query->get( $this->rewrite_ids['single_item'] );
     797            $member_type_slug      = $query->get( $this->rewrite_ids['directory_type'] );
     798
     799            if ( $member_slug ) {
     800                /**
     801                 * Filter the portion of the URI that is the displayed user's slug.
     802                 *
     803                 * Eg. example.com/ADMIN (when root profiles is enabled)
     804                 *     example.com/members/ADMIN (when root profiles isn't enabled)
     805                 *
     806                 * ADMIN would be the displayed user's slug.
     807                 *
     808                 * @since 2.6.0
     809                 *
     810                 * @param string $member_slug
     811                 */
     812                $member_slug           = apply_filters( 'bp_core_set_uri_globals_member_slug', $member_slug );
     813                $bp->current_component = '';
     814
     815                // Unless root profiles are on, the member shouldn't be set yet.
     816                if ( ! $member ) {
     817                    $member = get_user_by( $member_data['field'], $member_slug );
     818
     819                    if ( ! $member ) {
     820                        bp_do_404();
     821                        return;
     822                    }
     823                }
     824
     825                // If the member is marked as a spammer, 404 (unless logged-in user is a super admin).
     826                if ( bp_is_user_spammer( $member->ID ) ) {
     827                    if ( bp_current_user_can( 'bp_moderate' ) ) {
     828                        bp_core_add_message( __( 'This user has been marked as a spammer. Only site admins can view this profile.', 'buddypress' ), 'warning' );
     829                    } else {
     830                        bp_do_404();
     831                        return;
     832                    }
     833                }
     834
     835                // Set the displayed user and the current item.
     836                $bp->displayed_user->id = $member->ID;
     837                $bp->current_item       = $member_slug;
     838
     839                // The core userdata of the user who is currently being displayed.
     840                if ( ! isset( $bp->displayed_user->userdata ) || ! $bp->displayed_user->userdata ) {
     841                    $bp->displayed_user->userdata = bp_core_get_core_userdata( bp_displayed_user_id() );
     842                }
     843
     844                // Fetch the full name displayed user.
     845                if ( ! isset( $bp->displayed_user->fullname ) || ! $bp->displayed_user->fullname ) {
     846                    $bp->displayed_user->fullname = '';
     847                    if ( isset( $bp->displayed_user->userdata->display_name ) ) {
     848                        $bp->displayed_user->fullname = $bp->displayed_user->userdata->display_name;
     849                    }
     850                }
     851
     852                // The domain for the user currently being displayed.
     853                if ( ! isset( $bp->displayed_user->domain ) || ! $bp->displayed_user->domain ) {
     854                    $bp->displayed_user->domain = bp_members_get_user_url( bp_displayed_user_id() );
     855                }
     856
     857                // If A user is displayed, check if there is a front template.
     858                if ( bp_get_displayed_user() ) {
     859                    $bp->displayed_user->front_template = bp_displayed_user_get_front_template();
     860                }
     861
     862                $member_component = $query->get( $this->rewrite_ids['single_item_component'] );
     863                if ( $member_component ) {
     864                    // Check if the member's component slug has been customized.
     865                    $item_component_rewrite_id = bp_rewrites_get_custom_slug_rewrite_id( 'members', $member_component );
     866                    if ( $item_component_rewrite_id ) {
     867                        $member_component = str_replace( 'bp_member_', '', $item_component_rewrite_id );
     868                    }
     869
     870                    $bp->current_component = $member_component;
     871                }
     872
     873                $current_action = $query->get( $this->rewrite_ids['single_item_action'] );
     874                if ( $current_action ) {
     875                    $context = sprintf( 'bp_member_%s_', $bp->current_component );
     876
     877                    // Check if the member's component action slug has been customized.
     878                    $item_component_action_rewrite_id = bp_rewrites_get_custom_slug_rewrite_id( 'members', $current_action, $context );
     879                    if ( $item_component_action_rewrite_id ) {
     880                        $custom_action_slug = str_replace( $context, '', $item_component_action_rewrite_id );
     881
     882                        // Make sure the action is stored as a slug: underscores need to be replaced by dashes.
     883                        $current_action = str_replace( '_', '-', $custom_action_slug );
     884                    }
     885
     886                    $bp->current_action = $current_action;
     887                }
     888
     889                $action_variables = $query->get( $this->rewrite_ids['single_item_action_variables'] );
     890                if ( $action_variables ) {
     891                    if ( ! is_array( $action_variables ) ) {
     892                        $bp->action_variables = explode( '/', ltrim( $action_variables, '/' ) );
     893                    } else {
     894                        $bp->action_variables = $action_variables;
     895                    }
     896                }
     897
     898                // Is this a member type query?
     899            } elseif ( $member_type_slug ) {
     900                $member_type = bp_get_member_types(
     901                    array(
     902                        'has_directory'  => true,
     903                        'directory_slug' => $member_type_slug,
     904                    )
     905                );
     906
     907                if ( $member_type ) {
     908                    $member_type             = reset( $member_type );
     909                    $bp->current_member_type = $member_type;
     910                } else {
     911                    $bp->current_component = '';
     912                    bp_do_404();
     913                    return;
     914                }
     915            }
     916
     917            // Set the BuddyPress queried object.
     918            if ( isset( $bp->pages->members->id ) ) {
     919                $query->queried_object    = get_post( $bp->pages->members->id );
     920                $query->queried_object_id = $query->queried_object->ID;
     921
     922                if ( $member ) {
     923                    $query->queried_object->single_item_name = $member->display_name;
     924                } elseif ( $member_type ) {
     925                    $query->queried_object->directory_type_name = $member_type;
     926                }
     927            }
     928
     929            // Handle the custom registration page.
     930        } elseif ( $is_register_component ) {
     931            $bp->current_component = 'register';
     932
     933            // Handle the custom activation page.
     934        } elseif ( $is_activate_component ) {
     935            $bp->current_component = 'activate';
     936
     937            $current_action = $query->get( $this->rewrite_ids['member_activate_key'] );
     938            if ( $current_action ) {
     939                $bp->current_action = $current_action;
     940            }
     941        }
     942
     943        parent::parse_query( $query );
     944    }
     945
     946    /**
    761947     * Init the BP REST API.
    762948     *
Note: See TracChangeset for help on using the changeset viewer.