Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Manage bp_nav & bp_options_nav backcompat in this plugin #14

Merged
merged 1 commit into from
Jun 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
273 changes: 273 additions & 0 deletions inc/core/classes/class-bp-classic-core-legacy-nav-backcompat.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,273 @@
<?php
/**
* Backward compatibility for the $bp->bp_nav global.
*
* @package bp-classic\inc\groups\classes
* @since 1.0.0
*/

// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}

/**
* Backward compatibility class for the `bp_nav` global.
*
* This class is used to provide backward compatibility for extensions that access and modify
* the $bp->bp_nav global.
*
* @since 1.0.0
*/
class BP_Classic_Core_Legacy_Nav_BackCompat implements ArrayAccess {
/**
* Nav items.
*
* @since 1.0.0
* @access public
* @var array
*/
public $backcompat_nav = array();

/**
* Component to which nav items belong.
*
* @since 1.0.0
* @access public
* @var array
*/
public $component;

/**
* Constructor.
*
* @since 1.0.0
*
* @param array $backcompat_nav Optional. Array of nav items.
*/
public function __construct( $backcompat_nav = array() ) {
foreach ( $backcompat_nav as $key => $value ) {
if ( is_array( $value ) ) {
$this->backcompat_nav[ $key ] = new self( $value );
} else {
$this->backcompat_nav[ $key ] = $value;
}
}
}

/**
* Assign a value to the nav array at the specified offset.
*
* @since 1.0.0
*
* @param mixed $offset Array offset.
* @param array $value Nav item.
*/
#[ReturnTypeWillChange]
public function offsetSet( $offset, $value ) {
_doing_it_wrong(
'bp_nav',
esc_html__( 'The bp_nav and bp_options_nav globals should not be used directly and are deprecated. Please use the BuddyPress nav functions instead.', 'bp-classic' ),
'BuddyPress 2.6.0'
);

$bp = buddypress();

if ( is_array( $value ) ) {
$value = new self( $value );
}

if ( null !== $offset ) {
// Temporarily set the backcompat_nav.
$this->backcompat_nav[ $offset ] = $value;

$args = $this->to_array();
if ( isset( $args['parent_slug'] ) ) {
$this->get_component_nav( $args['parent_slug'] )->edit_nav( $args, $args['slug'], $args['parent_slug'] );
} elseif ( isset( $args['slug'] ) ) {
$bp->members->nav->edit_nav( $args, $args['slug'] );
}
}
}

/**
* Get a value of the nav array at the specified offset.
*
* @since 1.0.0
*
* @param mixed $offset Array offset.
* @return BP_Classic_Core_Legacy_Nav_BackCompat
*/
#[ReturnTypeWillChange]
public function offsetGet( $offset ) {
_doing_it_wrong(
'bp_nav',
esc_html__( 'The bp_nav and bp_options_nav globals should not be used directly and are deprecated. Please use the BuddyPress nav functions instead.', 'bp-classic' ),
'BuddyPress 2.6.0'
);

$nav = $this->get_nav( $offset );
if ( $nav && isset( $nav[ $offset ] ) ) {
$this->backcompat_nav[ $offset ] = new self( $nav[ $offset ] );
}

return $this->backcompat_nav[ $offset ];
}

/**
* Check whether nav array has a value at the specified offset.
*
* @since 1.0.0
*
* @param mixed $offset Array offset.
* @return bool
*/
#[ReturnTypeWillChange]
public function offsetExists( $offset ) {
_doing_it_wrong(
'bp_nav',
esc_html__( 'The bp_nav and bp_options_nav globals should not be used directly and are deprecated. Please use the BuddyPress nav functions instead.', 'bp-classic' ),
'BuddyPress 2.6.0'
);

if ( isset( $this->backcompat_nav[ $offset ] ) ) {
return true;
}

$nav = $this->get_nav( $offset );
if ( $nav && isset( $nav[ $offset ] ) ) {
return true;
}

return false;
}

/**
* Unset a nav array value at the specified offset.
*
* @since 1.0.0
*
* @param mixed $offset Array offset.
*/
#[ReturnTypeWillChange]
public function offsetUnset( $offset ) {
_doing_it_wrong(
'bp_nav',
esc_html__( 'The bp_nav and bp_options_nav globals should not be used directly and are deprecated. Please use the BuddyPress nav functions instead.', 'bp-classic' ),
'BuddyPress 2.6.0'
);

// For top-level nav items, the backcompat nav hasn't yet been initialized.
if ( ! isset( $this->backcompat_nav[ $offset ] ) ) {
buddypress()->members->nav->delete_nav( $offset );
unset( $this->backcompat_nav[ $offset ] );
}
}

/**
* Set the component to which the nav belongs.
*
* @since 1.0.0
*
* @param string $component The ID of the component.
*/
public function set_component( $component ) {
$this->component = $component;
}

/**
* Get the component to which the a nav item belongs.
*
* We use the following heuristic to guess, based on an offset, which component the item belongs to:
* - If this is a group, and the offset is the same as the current group's slug, it's a group nav item.
* - Otherwise, it's a member nav item.
*
* @since 1.0.0
*
* @param mixed $offset Array offset.
* @return string|array
*/
public function get_component( $offset = '' ) {
if ( ! isset( $this->component ) ) {
if ( bp_is_active( 'groups' ) && bp_get_current_group_slug() === $offset ) {
$this->component = 'groups';
} else {
$this->component = 'members';
}
}

return $this->component;
}

/**
* Reset the cached nav items.
*
* Called when the nav API removes items from the nav array.
*
* @since 1.0.0
*/
public function reset() {
$this->backcompat_nav = array();
}

/**
* Get the nav object corresponding to the specified offset.
*
* @since 1.0.0
*
* @param mixed $offset Array offset.
* @return bool|array
*/
protected function get_nav( $offset ) {
$component_nav = $this->get_component_nav( $offset );
$primary_nav = $component_nav->get_primary( array( 'slug' => $offset ), false );

$nav = array();

if ( empty( $primary_nav ) ) {
return $nav;
}

foreach ( $primary_nav as $item ) {
$nav[ $item->slug ] = (array) $item;
}

return $nav;
}

/**
* Get the BP_Core_Nav object corresponding to the component, based on a nav item name.
*
* The way bp_nav was previously organized makes it impossible to know for sure which component's nav is
* being referenced by a given nav item name. We guess in the following manner:
* - If we're looking at a group, and the nav item name (`$offset`) is the same as the slug of the current
* group, we assume that the proper component nav is 'groups'.
* - Otherwise, fall back on 'members'.
*
* @since 1.0.0
*
* @param string $offset Nav item name.
* @return BP_Core_Nav
*/
protected function get_component_nav( $offset = '' ) {
$component = $this->get_component( $offset );

$bp = buddypress();
if ( ! isset( $bp->{$component}->nav ) ) {
return false;
}

return $bp->{$component}->nav;
}

/**
* Get the nav data, formatted as a flat array.
*
* @since 1.0.0
*
* @return array
*/
protected function to_array() {
return $this->backcompat_nav;
}
}
Loading