Skip to content

Commit

Permalink
Manage bp_nav & bp_options_nav backcompat in this plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
imath authored Jun 26, 2023
1 parent d08104f commit 8a5e1ef
Show file tree
Hide file tree
Showing 4 changed files with 1,500 additions and 0 deletions.
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

0 comments on commit 8a5e1ef

Please sign in to comment.