Your IP : 216.73.216.162


Current Path : /home/x/b/o/xbodynamge/namtation/wp-content/
Upload File :
Current File : /home/x/b/o/xbodynamge/namtation/wp-content/BuddyPress.tar

Sitemap.php000066600000015654151143000000006656 0ustar00<?php

namespace AIOSEO\Plugin\Common\Standalone\BuddyPress;

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

use AIOSEO\Plugin\Common\Integrations\BuddyPress as BuddyPressIntegration;

/**
 * BuddyPress Sitemap class.
 *
 * @since 4.7.6
 */
class Sitemap {
	/**
	 * Returns the indexes for the sitemap root index.
	 *
	 * @since 4.7.6
	 *
	 * @return array The indexes.
	 */
	public function indexes() {
		$indexes           = [];
		$includedPostTypes = array_flip( aioseo()->sitemap->helpers->includedPostTypes() );
		$filterPostTypes   = array_filter( [
			BuddyPressIntegration::isComponentActive( 'activity' ) && isset( $includedPostTypes['bp-activity'] ) ? 'bp-activity' : '',
			BuddyPressIntegration::isComponentActive( 'group' ) && isset( $includedPostTypes['bp-group'] ) ? 'bp-group' : '',
			BuddyPressIntegration::isComponentActive( 'member' ) && isset( $includedPostTypes['bp-member'] ) ? 'bp-member' : '',
		] );

		foreach ( $filterPostTypes as $postType ) {
			$indexes = array_merge( $indexes, $this->buildIndexesPostType( $postType ) );
		}

		return $indexes;
	}

	/**
	 * Builds BuddyPress related root indexes.
	 *
	 * @since 4.7.6
	 *
	 * @param  string $postType The BuddyPress fake post type.
	 * @return array            The BuddyPress related root indexes.
	 */
	private function buildIndexesPostType( $postType ) {
		switch ( $postType ) {
			case 'bp-activity':
				return $this->buildIndexesActivity();
			case 'bp-group':
				return $this->buildIndexesGroup();
			case 'bp-member':
				return $this->buildIndexesMember();
			default:
				return [];
		}
	}

	/**
	 * Builds activity root indexes.
	 *
	 * @since 4.7.6
	 *
	 * @return array The activity root indexes.
	 */
	private function buildIndexesActivity() {
		$activityTable = aioseo()->core->db->prefix . 'bp_activity';
		$linksPerIndex = aioseo()->sitemap->linksPerIndex;
		$items         = aioseo()->core->db->execute(
			aioseo()->core->db->db->prepare(
				"SELECT id, date_recorded
				FROM (
					SELECT @row := @row + 1 AS rownum, id, date_recorded
					FROM (
						SELECT a.id, a.date_recorded FROM $activityTable as a
						WHERE a.is_spam = 0
							AND a.hide_sitewide = 0
							AND a.type NOT IN ('activity_comment', 'last_activity')
						ORDER BY a.date_recorded DESC
					) AS x
					CROSS JOIN (SELECT @row := 0) AS vars
					ORDER BY date_recorded DESC
				) AS y
				WHERE rownum = 1 OR rownum % %d = 1;",
				[
					$linksPerIndex
				]
			),
			true
		)->result();

		$totalItems = aioseo()->core->db->execute(
			"SELECT COUNT(*) as count
			FROM $activityTable as a
			WHERE a.is_spam = 0
				AND a.hide_sitewide = 0
				AND a.type NOT IN ('activity_comment', 'last_activity')
			",
			true
		)->result();

		$indexes = [];
		if ( $items ) {
			$filename = aioseo()->sitemap->filename;
			$count    = count( $items );
			for ( $i = 0; $i < $count; $i++ ) {
				$indexNumber = 0 !== $i && 1 < $count ? $i + 1 : '';

				$indexes[] = [
					'loc'     => aioseo()->helpers->localizedUrl( "/bp-activity-$filename$indexNumber.xml" ),
					'lastmod' => aioseo()->helpers->dateTimeToIso8601( $items[ $i ]->date_recorded ),
					'count'   => $linksPerIndex
				];
			}

			// We need to update the count of the last index since it won't necessarily be the same as the links per index.
			$indexes[ count( $indexes ) - 1 ]['count'] = $totalItems[0]->count - ( $linksPerIndex * ( $count - 1 ) );
		}

		return $indexes;
	}

	/**
	 * Builds group root indexes.
	 *
	 * @since 4.7.6
	 *
	 * @return array The group root indexes.
	 */
	private function buildIndexesGroup() {
		$groupsTable     = aioseo()->core->db->prefix . 'bp_groups';
		$groupsMetaTable = aioseo()->core->db->prefix . 'bp_groups_groupmeta';
		$linksPerIndex   = aioseo()->sitemap->linksPerIndex;
		$items           = aioseo()->core->db->execute(
			aioseo()->core->db->db->prepare(
				"SELECT id, date_modified
				FROM (
					SELECT @row := @row + 1 AS rownum, id, date_modified
					FROM (
						SELECT g.id, gm.group_id, MAX(gm.meta_value) as date_modified FROM $groupsTable as g
						INNER JOIN $groupsMetaTable AS gm ON g.id = gm.group_id
						WHERE g.status = 'public'
							AND gm.meta_key = 'last_activity'
						GROUP BY g.id
						ORDER BY date_modified DESC
					) AS x
					CROSS JOIN (SELECT @row := 0) AS vars
					ORDER BY date_modified DESC
				) AS y
				WHERE rownum = 1 OR rownum % %d = 1;",
				[
					$linksPerIndex
				]
			),
			true
		)->result();

		$totalItems = aioseo()->core->db->execute(
			"SELECT COUNT(*) as count
			FROM $groupsTable as g
			WHERE g.status = 'public'
			",
			true
		)->result();

		$indexes = [];
		if ( $items ) {
			$filename = aioseo()->sitemap->filename;
			$count    = count( $items );
			for ( $i = 0; $i < $count; $i++ ) {
				$indexNumber = 0 !== $i && 1 < $count ? $i + 1 : '';

				$indexes[] = [
					'loc'     => aioseo()->helpers->localizedUrl( "/bp-group-$filename$indexNumber.xml" ),
					'lastmod' => aioseo()->helpers->dateTimeToIso8601( $items[ $i ]->date_modified ),
					'count'   => $linksPerIndex
				];
			}

			// We need to update the count of the last index since it won't necessarily be the same as the links per index.
			$indexes[ count( $indexes ) - 1 ]['count'] = $totalItems[0]->count - ( $linksPerIndex * ( $count - 1 ) );
		}

		return $indexes;
	}

	/**
	 * Builds member root indexes.
	 *
	 * @since 4.7.6
	 *
	 * @return array The member root indexes.
	 */
	private function buildIndexesMember() {
		$activityTable = aioseo()->core->db->prefix . 'bp_activity';
		$linksPerIndex = aioseo()->sitemap->linksPerIndex;
		$items         = aioseo()->core->db->execute(
			aioseo()->core->db->db->prepare(
				"SELECT user_id, date_recorded
				FROM (
					SELECT @row := @row + 1 AS rownum, user_id, date_recorded
					FROM (
						SELECT a.user_id, a.date_recorded FROM $activityTable as a
						WHERE a.component = 'members'
							AND a.type = 'last_activity'
						ORDER BY a.date_recorded DESC
					) AS x
					CROSS JOIN (SELECT @row := 0) AS vars
					ORDER BY date_recorded DESC
				) AS y
				WHERE rownum = 1 OR rownum % %d = 1;",
				[
					$linksPerIndex
				]
			),
			true
		)->result();

		$totalItems = aioseo()->core->db->execute(
			"SELECT COUNT(*) as count
			FROM $activityTable as a
			WHERE a.component = 'members'
				AND a.type = 'last_activity'
			",
			true
		)->result();

		$indexes = [];
		if ( $items ) {
			$filename = aioseo()->sitemap->filename;
			$count    = count( $items );
			for ( $i = 0; $i < $count; $i++ ) {
				$indexNumber = 0 !== $i && 1 < $count ? $i + 1 : '';

				$indexes[] = [
					'loc'     => aioseo()->helpers->localizedUrl( "/bp-member-$filename$indexNumber.xml" ),
					'lastmod' => aioseo()->helpers->dateTimeToIso8601( $items[ $i ]->date_recorded ),
					'count'   => $linksPerIndex
				];
			}

			// We need to update the count of the last index since it won't necessarily be the same as the links per index.
			$indexes[ count( $indexes ) - 1 ]['count'] = $totalItems[0]->count - ( $linksPerIndex * ( $count - 1 ) );
		}

		return $indexes;
	}
}Component.php000066600000030273151143000000007210 0ustar00<?php
namespace AIOSEO\Plugin\Common\Standalone\BuddyPress;

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

use AIOSEO\Plugin\Common\Integrations\BuddyPress as BuddyPressIntegration;
use AIOSEO\Plugin\Common\Schema\Graphs as CommonGraphs;

/**
 * BuddyPress Component class.
 *
 * @since 4.7.6
 */
class Component {
	/**
	 * The current component template type.
	 *
	 * @since 4.7.6
	 *
	 * @var string|null
	 */
	public $templateType = null;

	/**
	 * The component ID.
	 *
	 * @since 4.7.6
	 *
	 * @var int
	 */
	public $id = 0;

	/**
	 * The component author.
	 *
	 * @since 4.7.6
	 *
	 * @var \WP_User|false
	 */
	public $author = false;

	/**
	 * The component date.
	 *
	 * @since 4.7.6
	 *
	 * @var int|false
	 */
	public $date = false;

	/**
	 * The activity single page data.
	 *
	 * @since 4.7.6
	 *
	 * @var array
	 */
	public $activity = [];

	/**
	 * The group single page data.
	 *
	 * @since 4.7.6
	 *
	 * @var array
	 */
	public $group = [];

	/**
	 * The type of the group archive page.
	 *
	 * @since 4.7.6
	 *
	 * @var array
	 */
	public $groupType = [];

	/**
	 * Class constructor.
	 *
	 * @since 4.7.6
	 */
	public function __construct() {
		if ( is_admin() ) {
			return;
		}

		$this->setTemplateType();
		$this->setId();
		$this->setAuthor();
		$this->setDate();
		$this->setActivity();
		$this->setGroup();
		$this->setGroupType();
	}

	/**
	 * Sets the template type.
	 *
	 * @since 4.7.6
	 *
	 * @return void
	 */
	private function setTemplateType() {
		if ( BuddyPressIntegration::callFunc( 'bp_is_single_activity' ) ) {
			$this->templateType = 'bp-activity_single';
		} elseif ( BuddyPressIntegration::callFunc( 'bp_is_group' ) ) {
			$this->templateType = 'bp-group_single';
		} elseif (
			BuddyPressIntegration::callFunc( 'bp_is_user' ) &&
			false === BuddyPressIntegration::callFunc( 'bp_is_single_activity' )
		) {
			$this->templateType = 'bp-member_single';
		} elseif ( BuddyPressIntegration::callFunc( 'bp_is_activity_directory' ) ) {
			$this->templateType = 'bp-activity_archive';
		} elseif ( BuddyPressIntegration::callFunc( 'bp_is_members_directory' ) ) {
			$this->templateType = 'bp-member_archive';
		} elseif ( BuddyPressIntegration::callFunc( 'bp_is_groups_directory' ) ) {
			$this->templateType = 'bp-group_archive';
		} elseif (
			BuddyPressIntegration::callFunc( 'bp_is_current_action', 'feed' ) &&
			BuddyPressIntegration::callFunc( 'bp_is_activity_component' )
		) {
			$this->templateType = 'bp-activity_feed';
		}
	}

	/**
	 * Sets the component ID.
	 *
	 * @since 4.7.6
	 *
	 * @return void
	 */
	private function setId() {
		switch ( $this->templateType ) {
			case 'bp-activity_single':
				$id = get_query_var( 'bp_member_action' );
				break;
			case 'bp-group_single':
				$id = get_query_var( 'bp_group' );
				break;
			case 'bp-member_single':
				$id = get_query_var( 'bp_member' );
				break;
			default:
				$id = $this->id;
		}

		$this->id = $id;
	}

	/**
	 * Sets the component author.
	 *
	 * @since 4.7.6
	 *
	 * @return void
	 */
	private function setAuthor() {
		switch ( $this->templateType ) {
			case 'bp-activity_single':
				if ( ! $this->activity ) {
					$this->setActivity();
				}

				if ( $this->activity ) {
					$this->author = get_user_by( 'id', $this->activity['user_id'] );

					return;
				}

				break;
			case 'bp-group_single':
				if ( ! $this->group ) {
					$this->setGroup();
				}

				if ( $this->group ) {
					$this->author = get_user_by( 'id', $this->group['creator_id'] );

					return;
				}

				break;
			case 'bp-member_single':
				$this->author = get_user_by( 'slug', $this->id );

				return;
		}
	}

	/**
	 * Sets the component date.
	 *
	 * @since 4.7.6
	 *
	 * @return void
	 */
	private function setDate() {
		switch ( $this->templateType ) {
			case 'bp-activity_single':
				if ( ! $this->activity ) {
					$this->setActivity();
				}
				$date = strtotime( $this->activity['date_recorded'] );
				break;
			case 'bp-group_single':
				if ( ! $this->group ) {
					$this->setGroup();
				}
				$date = strtotime( $this->group['date_created'] );
				break;
			default:
				$date = $this->date;
		}

		$this->date = $date;
	}

	/**
	 * Sets the activity data.
	 *
	 * @since 4.7.6
	 *
	 * @return void
	 */
	private function setActivity() {
		if ( 'bp-activity_single' !== $this->templateType ) {
			return;
		}

		$activities = BuddyPressIntegration::callFunc( 'bp_activity_get_specific', [
			'activity_ids'     => [ $this->id ],
			'display_comments' => true
		] );
		if ( ! empty( $activities['activities'] ) ) {
			list( $activity ) = current( $activities );

			$this->activity = (array) $activity;

			// The `content_rendered` is AIOSEO specific.
			$this->activity['content_rendered'] = $this->activity['content'] ?? '';
			if ( ! empty( $this->activity['content'] ) ) {
				$this->activity['content_rendered'] = apply_filters( 'bp_get_activity_content', $this->activity['content'] );
			}

			return;
		}

		$this->resetComponent();
	}

	/**
	 * Sets the group data.
	 *
	 * @since 4.7.6
	 *
	 * @return void
	 */
	private function setGroup() {
		if ( 'bp-group_single' !== $this->templateType ) {
			return;
		}

		$group = BuddyPressIntegration::callFunc( 'bp_get_group_by', 'slug', $this->id );
		if ( ! empty( $group ) ) {
			$this->group = (array) $group;

			return;
		}

		$this->resetComponent();
	}

	/**
	 * Sets the group type.
	 *
	 * @since 4.7.6
	 *
	 * @return void
	 */
	private function setGroupType() {
		if ( 'bp-group_archive' !== $this->templateType ) {
			return;
		}

		$type = BuddyPressIntegration::callFunc( 'bp_get_current_group_directory_type' );
		if ( ! $type ) {
			return;
		}

		$term = get_term_by( 'slug', $type, 'bp_group_type' );
		if ( ! $term ) {
			return;
		}

		$meta = get_metadata( 'term', $term->term_id );
		if ( ! $meta ) {
			return;
		}

		$this->groupType = [
			'singular' => $meta['bp_type_singular_name'][0] ?? '',
			'plural'   => $meta['bp_type_name'][0] ?? '',
		];
	}

	/**
	 * Resets some of the component properties.
	 *
	 * @since 4.7.6
	 *
	 * @return void
	 */
	private function resetComponent() {
		$this->templateType = null;
		$this->id           = 0;
	}

	/**
	 * Retrieves the SEO metadata value.
	 *
	 * @since 4.7.6
	 *
	 * @param  string $which The SEO metadata to get.
	 * @return string        The SEO metadata value.
	 */
	public function getMeta( $which ) {
		list( $postType, $suffix ) = explode( '_', $this->templateType );

		switch ( $which ) {
			case 'title':
				$meta = 'single' === $suffix
					? aioseo()->meta->title->getPostTypeTitle( $postType )
					: aioseo()->meta->title->getArchiveTitle( $postType );
				$meta = aioseo()->meta->description->helpers->bpSanitize( $meta, $this->id );
				break;
			case 'description':
				$meta = 'single' === $suffix
					? aioseo()->meta->description->getPostTypeDescription( $postType )
					: aioseo()->meta->description->getArchiveDescription( $postType );
				$meta = aioseo()->meta->description->helpers->bpSanitize( $meta, $this->id );
				break;
			case 'keywords':
				$meta = 'single' === $suffix
					? ''
					: aioseo()->meta->keywords->getArchiveKeywords( $postType );
				$meta = aioseo()->meta->keywords->prepareKeywords( $meta );
				break;
			case 'robots':
				$dynamicOptions = aioseo()->dynamicOptions->noConflict();
				if ( 'single' === $suffix && $dynamicOptions->searchAppearance->postTypes->has( $postType ) ) {
					aioseo()->meta->robots->globalValues( [ 'postTypes', $postType ], true );
				} elseif ( $dynamicOptions->searchAppearance->archives->has( $postType ) ) {
					aioseo()->meta->robots->globalValues( [ 'archives', $postType ], true );
				}

				$meta = aioseo()->meta->robots->metaHelper();
				break;
			case 'canonical':
				$meta = '';
				if ( 'single' === $suffix ) {
					if ( 'bp-member' === $postType ) {
						$meta = BuddyPressIntegration::getComponentSingleUrl( 'member', $this->author->ID );
					} elseif ( 'bp-group' === $postType ) {
						$meta = BuddyPressIntegration::getComponentSingleUrl( 'group', $this->group['id'] );
					}
				}
				break;
			default:
				$meta = '';
		}

		return $meta;
	}

	/**
	 * Determines the schema type for the current component.
	 *
	 * @since 4.7.6
	 *
	 * @param  \AIOSEO\Plugin\Common\Schema\Context $contextInstance The Context class instance.
	 * @return void
	 */
	public function determineSchemaGraphsAndContext( $contextInstance ) {
		list( $postType ) = explode( '_', $this->templateType );

		$dynamicOptions = aioseo()->dynamicOptions->noConflict();
		if ( $dynamicOptions->searchAppearance->postTypes->has( $postType ) ) {
			$defaultType = $dynamicOptions->searchAppearance->postTypes->{$postType}->schemaType;
			switch ( $defaultType ) {
				case 'Article':
					aioseo()->schema->graphs[] = $dynamicOptions->searchAppearance->postTypes->{$postType}->articleType;
					break;
				case 'WebPage':
					aioseo()->schema->graphs[] = $dynamicOptions->searchAppearance->postTypes->{$postType}->webPageType;
					break;
				default:
					aioseo()->schema->graphs[] = $defaultType;
			}
		}

		switch ( $this->templateType ) {
			case 'bp-activity_single':
				$datePublished = $this->activity['date_recorded'];
				$contextUrl    = BuddyPressIntegration::getComponentSingleUrl( 'activity', $this->activity['id'] );

				break;
			case 'bp-group_single':
				$datePublished = $this->group['date_created'];
				$contextUrl    = BuddyPressIntegration::getComponentSingleUrl( 'group', $this->group['id'] );

				break;
			case 'bp-member_single':
				aioseo()->schema->graphs[] = 'ProfilePage';

				$contextUrl = BuddyPressIntegration::getComponentSingleUrl( 'member', $this->author->ID );

				break;
			case 'bp-activity_archive':
			case 'bp-group_archive':
			case 'bp-member_archive':
				list( , $component ) = explode( '-', $postType );

				$contextUrl     = BuddyPressIntegration::getComponentArchiveUrl( $component );
				$breadcrumbType = 'CollectionPage';

				break;
			default:
				break;
		}

		if ( ! empty( $datePublished ) ) {
			CommonGraphs\Article\NewsArticle::setOverwriteGraphData( [
				'properties' => compact( 'datePublished' )
			] );
		}

		if ( ! empty( $contextUrl ) ) {
			$name                = aioseo()->meta->title->getTitle();
			$description         = aioseo()->meta->description->getDescription();
			$breadcrumbPositions = [
				'name'        => $name,
				'description' => $description,
				'url'         => $contextUrl,
			];

			if ( ! empty( $breadcrumbType ) ) {
				$breadcrumbPositions['type'] = $breadcrumbType;
			}

			aioseo()->schema->context = [
				'name'        => $name,
				'description' => $description,
				'url'         => $contextUrl,
				'breadcrumb'  => $contextInstance->breadcrumb->setPositions( $breadcrumbPositions ),
			];
		}
	}

	/**
	 * Gets the breadcrumbs for the current component.
	 *
	 * @since 4.7.6
	 *
	 * @return array
	 */
	public function getCrumbs() {
		$crumbs = [];
		switch ( $this->templateType ) {
			case 'bp-activity_single':
				$crumbs[] = aioseo()->breadcrumbs->makeCrumb(
					BuddyPressIntegration::callFunc( 'bp_get_directory_title', 'activity' ),
					BuddyPressIntegration::getComponentArchiveUrl( 'activity' )
				);
				$crumbs[] = aioseo()->breadcrumbs->makeCrumb( sanitize_text_field( $this->activity['action'] ) );
				break;
			case 'bp-group_single':
				$crumbs[] = aioseo()->breadcrumbs->makeCrumb(
					BuddyPressIntegration::callFunc( 'bp_get_directory_title', 'groups' ),
					BuddyPressIntegration::getComponentArchiveUrl( 'group' )
				);
				$crumbs[] = aioseo()->breadcrumbs->makeCrumb( $this->group['name'] );
				break;
			case 'bp-member_single':
				$crumbs[] = aioseo()->breadcrumbs->makeCrumb(
					BuddyPressIntegration::callFunc( 'bp_get_directory_title', 'members' ),
					BuddyPressIntegration::getComponentArchiveUrl( 'member' )
				);
				$crumbs[] = aioseo()->breadcrumbs->makeCrumb( $this->author->display_name );
				break;
			case 'bp-activity_archive':
				$crumbs[] = aioseo()->breadcrumbs->makeCrumb( BuddyPressIntegration::callFunc( 'bp_get_directory_title', 'activity' ) );
				break;
			case 'bp-group_archive':
				$crumbs[] = aioseo()->breadcrumbs->makeCrumb( BuddyPressIntegration::callFunc( 'bp_get_directory_title', 'groups' ) );
				break;
			case 'bp-member_archive':
				$crumbs[] = aioseo()->breadcrumbs->makeCrumb( BuddyPressIntegration::callFunc( 'bp_get_directory_title', 'members' ) );
				break;
			default:
				break;
		}

		return $crumbs;
	}
}BuddyPress.php000066600000023313151143000000007327 0ustar00<?php
namespace AIOSEO\Plugin\Common\Standalone\BuddyPress;

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

use AIOSEO\Plugin\Common\Integrations\BuddyPress as BuddyPressIntegration;

/**
 * Handles the BuddyPress integration with AIOSEO.
 *
 * @since 4.7.6
 */
class BuddyPress {
	/**
	 * Instance of the Tags class.
	 *
	 * @since 4.7.6
	 *
	 * @var Tags
	 */
	public $tags;

	/**
	 * Instance of the Component class.
	 *
	 * @since 4.7.6
	 *
	 * @var Component
	 */
	public $component;

	/**
	 * Instance of the Sitemap class.
	 *
	 * @since 4.7.6
	 *
	 * @var Sitemap
	 */
	public $sitemap = null;

	/**
	 * Class constructor.
	 *
	 * @since 4.7.6
	 */
	public function __construct() {
		if (
			aioseo()->helpers->isAjaxCronRestRequest() ||
			! aioseo()->helpers->isPluginActive( 'buddypress' )
		) {
			return;
		}

		// Hook into `plugins_loaded` to ensure BuddyPress has loaded some necessary functions.
		add_action( 'plugins_loaded', [ $this, 'maybeLoad' ], 20 );
	}

	/**
	 * Hooked into `plugins_loaded` action hook.
	 *
	 * @since 4.7.6
	 *
	 * @return void
	 */
	public function maybeLoad() {
		// If the BuddyPress version is below 12 we bail.
		if ( ! function_exists( 'bp_get_version' ) || version_compare( bp_get_version(), '12', '<' ) ) {
			return;
		}

		// If none of the necessary BuddyPress components are active we bail.
		if (
			! BuddyPressIntegration::isComponentActive( 'activity' ) &&
			! BuddyPressIntegration::isComponentActive( 'group' ) &&
			! BuddyPressIntegration::isComponentActive( 'member' )
		) {
			return;
		}

		$this->sitemap = new Sitemap();

		add_action( 'init', [ $this, 'setTags' ], 20 );
		add_action( 'bp_parse_query', [ $this, 'setComponent' ], 20 );
	}

	/**
	 * Hooked into `init` action hook.
	 *
	 * @since 4.7.6
	 *
	 * @return void
	 */
	public function setTags() {
		$this->tags = new Tags();
	}

	/**
	 * Hooked into `bp_parse_query` action hook.
	 *
	 * @since 4.7.6
	 *
	 * @return void
	 */
	public function setComponent() {
		$this->component = new Component();
	}

	/**
	 * Adds the BuddyPress fake post types to the list of post types, so they appear under e.g. Search Appearance.
	 *
	 * @since 4.7.6
	 *
	 * @param  array $postTypes       Public post types from {@see \AIOSEO\Plugin\Common\Traits\Helpers\Wp::getPublicPostTypes}.
	 * @param  bool  $namesOnly       Whether only the names should be included.
	 * @param  bool  $hasArchivesOnly Whether to only include post types which have archives.
	 * @param  array $args            Additional arguments.
	 * @return void
	 */
	public function maybeAddPostTypes( &$postTypes, $namesOnly, $hasArchivesOnly, $args ) {
		// If one of these CPTs is already registered we bail, so we don't overwrite them and possibly break something.
		if (
			post_type_exists( 'bp-activity' ) ||
			post_type_exists( 'bp-group' ) ||
			post_type_exists( 'bp-member' )
		) {
			return;
		}

		/**
		 * The BP components are registered with the `buddypress` CPT which is not viewable, so we add it here to include our metadata inside <head>.
		 * {@see \AIOSEO\Plugin\Common\Main\Head::wpHead}.
		 */
		if (
			$namesOnly &&
			doing_action( 'wp_head' )
		) {
			$postTypes = array_merge( $postTypes, [ 'buddypress' ] );

			return;
		}

		$fakePostTypes = $this->getFakePostTypes();

		if ( ! BuddyPressIntegration::isComponentActive( 'activity' ) ) {
			unset( $fakePostTypes['bp-activity'] );
		}

		if ( ! BuddyPressIntegration::isComponentActive( 'group' ) ) {
			unset( $fakePostTypes['bp-group'] );
		}

		if ( ! BuddyPressIntegration::isComponentActive( 'member' ) ) {
			unset( $fakePostTypes['bp-member'] );
		}

		if ( $hasArchivesOnly ) {
			$fakePostTypes = array_filter( $fakePostTypes, function ( $postType ) {
				return $postType['hasArchive'];
			} );
		}

		if ( $namesOnly ) {
			$fakePostTypes = array_keys( $fakePostTypes );
		}

		// 0. Below we'll add/merge the BuddyPress post types only under certain conditions.
		$fakePostTypes = array_values( $fakePostTypes );
		$currentScreen = aioseo()->helpers->getCurrentScreen();

		if (
			// 1. If the `buddypress` CPT is set in the list of post types to be included.
			( ! empty( $args['include'] ) && in_array( 'buddypress', $args['include'], true ) ) ||
			// 2. If the current request is for the sitemap.
			( ! empty( aioseo()->sitemap->filename ) && 'general' === ( aioseo()->sitemap->type ?? '' ) ) ||
			// 3. If we're on the Search Appearance screen.
			( $currentScreen && strpos( $currentScreen->id, 'aioseo-search-appearance' ) !== false ) ||
			// 4. If we're on the BuddyPress component front-end screen.
			BuddyPressIntegration::isComponentPage()
		) {
			$postTypes = array_merge( $postTypes, $fakePostTypes );
		}
	}

	/**
	 * Get edit links for the SEO Preview data.
	 *
	 * @since 4.7.6
	 *
	 * @return array
	 */
	public function getVueDataSeoPreview() {
		$data = [
			'editGoogleSnippetUrl' => '',
			'editObjectBtnText'    => '',
			'editObjectUrl'        => '',
		];

		list( $postType, $suffix ) = explode( '_', aioseo()->standalone->buddyPress->component->templateType );

		$bpFakePostTypes  = $this->getFakePostTypes();
		$fakePostTypeData = array_values( wp_list_filter( $bpFakePostTypes, [ 'name' => $postType ] ) );
		$fakePostTypeData = $fakePostTypeData[0] ?? [];
		if ( ! $fakePostTypeData ) {
			return $data;
		}

		if ( 'single' === $suffix ) {
			switch ( $postType ) {
				case 'bp-activity':
					$componentId = aioseo()->standalone->buddyPress->component->activity['id'];
					break;
				case 'bp-group':
					$componentId = aioseo()->standalone->buddyPress->component->group['id'];
					break;
				case 'bp-member':
					$componentId = aioseo()->standalone->buddyPress->component->author->ID;
					break;
				default:
					$componentId = 0;
			}
		}

		$scrollToId                   = 'aioseo-card-' . $postType . ( 'single' === $suffix ? 'SA' : 'ArchiveArchives' );
		$data['editGoogleSnippetUrl'] = 'single' === $suffix
			? admin_url( 'admin.php?page=aioseo-search-appearance' ) . '#/content-types'
			: admin_url( 'admin.php?page=aioseo-search-appearance' ) . '#/archives';
		$data['editGoogleSnippetUrl'] = add_query_arg( [
			'aioseo-scroll'    => $scrollToId,
			'aioseo-highlight' => $scrollToId
		], $data['editGoogleSnippetUrl'] );

		$data['editObjectBtnText'] = sprintf(
			// Translators: 1 - A noun for something that's being edited ("Post", "Page", "Article", "Product", etc.).
			esc_html__( 'Edit %1$s', 'all-in-one-seo-pack' ),
			'single' === $suffix ? $fakePostTypeData['singular'] : $fakePostTypeData['label']
		);

		list( , $component ) = explode( '-', $postType );

		$data['editObjectUrl'] = 'single' === $suffix
			? BuddyPressIntegration::getComponentEditUrl( $component, $componentId ?? 0 )
			: BuddyPressIntegration::callFunc( 'bp_get_admin_url', add_query_arg( 'page', 'bp-rewrites', 'admin.php' ) );

		return $data;
	}

	/**
	 * Retrieves the BuddyPress fake post types.
	 *
	 * @since 4.7.6
	 *
	 * @return array The BuddyPress fake post types.
	 */
	public function getFakePostTypes() {
		return [
			'bp-activity' => [
				'name'               => 'bp-activity',
				'label'              => sprintf(
					// Translators: 1 - The hard coded string 'BuddyPress'.
					_x( 'Activities (%1$s)', 'BuddyPress', 'all-in-one-seo-pack' ),
					'BuddyPress'
				),
				'singular'           => 'Activity',
				'icon'               => 'dashicons-buddicons-buddypress-logo',
				'hasExcerpt'         => false,
				'hasArchive'         => true,
				'hierarchical'       => false,
				'taxonomies'         => [],
				'slug'               => 'bp-activity',
				'buddyPress'         => true,
				'defaultTags'        => [
					'postTypes' => [
						'title'       => [
							'bp_activity_action',
							'separator_sa',
							'site_title',
						],
						'description' => [
							'bp_activity_content',
							'separator_sa'
						]
					]
				],
				'defaultTitle'       => '#bp_activity_action #separator_sa #site_title',
				'defaultDescription' => '#bp_activity_content',
			],
			'bp-group'    => [
				'name'               => 'bp-group',
				'label'              => sprintf(
					// Translators: 1 - The hard coded string 'BuddyPress'.
					_x( 'Groups (%1$s)', 'BuddyPress', 'all-in-one-seo-pack' ),
					'BuddyPress'
				),
				'singular'           => 'Group',
				'icon'               => 'dashicons-buddicons-buddypress-logo',
				'hasExcerpt'         => false,
				'hasArchive'         => true,
				'hierarchical'       => false,
				'taxonomies'         => [],
				'slug'               => 'bp-group',
				'buddyPress'         => true,
				'defaultTags'        => [
					'postTypes' => [
						'title'       => [
							'bp_group_name',
							'separator_sa',
							'site_title',
						],
						'description' => [
							'bp_group_description',
							'separator_sa'
						]
					]
				],
				'defaultTitle'       => '#bp_group_name #separator_sa #site_title',
				'defaultDescription' => '#bp_group_description',
			],
			'bp-member'   => [
				'name'               => 'bp-member',
				'label'              => sprintf(
					// Translators: 1 - The hard coded string 'BuddyPress'.
					_x( 'Members (%1$s)', 'BuddyPress', 'all-in-one-seo-pack' ),
					'BuddyPress'
				),
				'singular'           => 'Member',
				'icon'               => 'dashicons-buddicons-buddypress-logo',
				'hasExcerpt'         => false,
				'hasArchive'         => true,
				'hierarchical'       => false,
				'taxonomies'         => [],
				'slug'               => 'bp-member',
				'buddyPress'         => true,
				'defaultTags'        => [
					'postTypes' => [
						'title'       => [
							'author_name',
							'separator_sa',
							'site_title',
						],
						'description' => [
							'author_bio',
							'separator_sa'
						]
					]
				],
				'defaultTitle'       => '#author_name #separator_sa #site_title',
				'defaultDescription' => '#author_bio',
			],
		];
	}
}Tags.php000066600000023531151143000000006143 0ustar00<?php
namespace AIOSEO\Plugin\Common\Standalone\BuddyPress;

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

/**
 * BuddyPress Tags class.
 *
 * @since 4.7.6
 */
class Tags {
	/**
	 * Class constructor.
	 *
	 * @since 4.7.6
	 */
	public function __construct() {
		aioseo()->tags->addContext( $this->getContexts() );
		aioseo()->tags->addTags( $this->getTags() );
	}

	/**
	 * Retrieves the contexts for BuddyPress.
	 *
	 * @since 4.7.6
	 *
	 * @return array An array of contextual data.
	 */
	public function getContexts() {
		return [
			'bp-activityTitle'              => [
				'author_first_name',
				'author_last_name',
				'author_name',
				'current_date',
				'current_day',
				'current_month',
				'current_year',
				'post_date',
				'post_day',
				'post_month',
				'post_year',
				'separator_sa',
				'site_title',
				'tagline',
				'bp_activity_action',
				'bp_activity_content',
			],
			'bp-activityArchiveTitle'       => [
				'current_date',
				'current_day',
				'current_month',
				'current_year',
				'separator_sa',
				'site_title',
				'tagline',
				'archive_title',
			],
			'bp-activityDescription'        => [
				'author_first_name',
				'author_last_name',
				'author_name',
				'current_date',
				'current_day',
				'current_month',
				'current_year',
				'post_date',
				'post_day',
				'post_month',
				'post_year',
				'separator_sa',
				'site_title',
				'tagline',
				'bp_activity_action',
				'bp_activity_content',
			],
			'bp-activityArchiveDescription' => [
				'current_date',
				'current_day',
				'current_month',
				'current_year',
				'separator_sa',
				'site_title',
				'tagline',
				'archive_title',
			],
			'bp-groupTitle'                 => [
				'author_first_name',
				'author_last_name',
				'author_name',
				'current_date',
				'current_day',
				'current_month',
				'current_year',
				'post_date',
				'post_day',
				'post_month',
				'post_year',
				'separator_sa',
				'site_title',
				'tagline',
				'bp_group_name',
				'bp_group_description',
			],
			'bp-groupArchiveTitle'          => [
				'current_date',
				'current_day',
				'current_month',
				'current_year',
				'separator_sa',
				'site_title',
				'tagline',
				'archive_title',
				'bp_group_type_singular_name',
				'bp_group_type_plural_name',
			],
			'bp-groupDescription'           => [
				'author_first_name',
				'author_last_name',
				'author_name',
				'current_date',
				'current_day',
				'current_month',
				'current_year',
				'post_date',
				'post_day',
				'post_month',
				'post_year',
				'separator_sa',
				'site_title',
				'tagline',
				'bp_group_name',
				'bp_group_description',
			],
			'bp-groupArchiveDescription'    => [
				'current_date',
				'current_day',
				'current_month',
				'current_year',
				'separator_sa',
				'site_title',
				'tagline',
				'archive_title',
				'bp_group_type_singular_name',
				'bp_group_type_plural_name',
			],
			'bp-memberTitle'                => [
				'author_first_name',
				'author_last_name',
				'author_name',
				'current_date',
				'current_day',
				'current_month',
				'current_year',
				'separator_sa',
				'site_title',
				'tagline',
			],
			'bp-memberArchiveTitle'         => [
				'current_date',
				'current_day',
				'current_month',
				'current_year',
				'separator_sa',
				'site_title',
				'tagline',
				'archive_title',
			],
			'bp-memberDescription'          => [
				'author_first_name',
				'author_last_name',
				'author_name',
				'author_bio',
				'current_date',
				'current_day',
				'current_month',
				'current_year',
				'separator_sa',
				'site_title',
				'tagline',
			],
			'bp-memberArchiveDescription'   => [
				'current_date',
				'current_day',
				'current_month',
				'current_year',
				'separator_sa',
				'site_title',
				'tagline',
				'archive_title',
			],
		];
	}

	/**
	 * Retrieves the custom tags for BuddyPress.
	 *
	 * @since 4.7.6
	 *
	 * @return array An array of tags.
	 */
	public function getTags() {
		return [
			[
				'id'          => 'bp_activity_action',
				'name'        => _x( 'Activity Action', 'BuddyPress', 'all-in-one-seo-pack' ),
				'description' => _x( 'The activity action.', 'BuddyPress', 'all-in-one-seo-pack' ),
				'instance'    => $this,
			],
			[
				'id'          => 'bp_activity_content',
				'name'        => _x( 'Activity Content', 'BuddyPress', 'all-in-one-seo-pack' ),
				'description' => _x( 'The activity content.', 'BuddyPress', 'all-in-one-seo-pack' ),
				'instance'    => $this,
			],
			[
				'id'          => 'bp_group_name',
				'name'        => _x( 'Group Name', 'BuddyPress', 'all-in-one-seo-pack' ),
				'description' => _x( 'The group name.', 'BuddyPress', 'all-in-one-seo-pack' ),
				'instance'    => $this,
			],
			[
				'id'          => 'bp_group_description',
				'name'        => _x( 'Group Description', 'BuddyPress', 'all-in-one-seo-pack' ),
				'description' => _x( 'The group description.', 'BuddyPress', 'all-in-one-seo-pack' ),
				'instance'    => $this,
			],
			[
				'id'          => 'bp_group_type_singular_name',
				'name'        => _x( 'Group Type Singular Name', 'BuddyPress', 'all-in-one-seo-pack' ),
				'description' => _x( 'The group type singular name.', 'BuddyPress', 'all-in-one-seo-pack' ),
				'instance'    => $this,
			],
			[
				'id'          => 'bp_group_type_plural_name',
				'name'        => _x( 'Group Type Plural Name', 'BuddyPress', 'all-in-one-seo-pack' ),
				'description' => _x( 'The group type plural name.', 'BuddyPress', 'all-in-one-seo-pack' ),
				'instance'    => $this,
			],
		];
	}

	/**
	 * Replace the tags in the string provided.
	 *
	 * @since 4.7.6
	 *
	 * @param  string $string The string to look for tags in.
	 * @param  int    $id     The object ID.
	 * @return string         The string with tags replaced.
	 */
	public function replaceTags( $string, $id ) {
		if ( ! $string || ! preg_match( '/' . aioseo()->tags->denotationChar . '/', $string ) ) {
			return $string;
		}

		foreach ( array_unique( aioseo()->helpers->flatten( $this->getContexts() ) ) as $tag ) {
			$tagId   = aioseo()->tags->denotationChar . $tag;
			$pattern = "/$tagId(?![a-zA-Z0-9_])/im";
			if ( preg_match( $pattern, $string ) ) {
				$tagValue = $this->getTagValue( [ 'id' => $tag ], $id );
				$string   = preg_replace( $pattern, '%|%' . aioseo()->helpers->escapeRegexReplacement( $tagValue ), $string );
			}
		}

		return str_replace( '%|%', '', $string );
	}

	/**
	 * Get the value of the tag to replace.
	 *
	 * @since 4.7.6
	 *
	 * @param  array    $tag        The tag to look for.
	 * @param  int|null $id         The object ID.
	 * @param  bool     $sampleData Whether to fill empty values with sample data.
	 * @return string               The value of the tag.
	 */
	public function getTagValue( $tag, $id = null, $sampleData = false ) {
		$sampleData = $sampleData || empty( aioseo()->standalone->buddyPress->component->templateType );

		switch ( $tag['id'] ) {
			case 'author_bio':
				$out = $sampleData
					? __( 'Sample author biography', 'all-in-one-seo-pack' )
					: aioseo()->standalone->buddyPress->component->author->description;
				break;
			case 'author_first_name':
				$out = $sampleData
					? wp_get_current_user()->first_name
					: aioseo()->standalone->buddyPress->component->author->first_name;
				break;
			case 'author_last_name':
				$out = $sampleData
					? wp_get_current_user()->last_name
					: aioseo()->standalone->buddyPress->component->author->last_name;
				break;
			case 'author_name':
				$out = $sampleData
					? wp_get_current_user()->display_name
					: aioseo()->standalone->buddyPress->component->author->display_name;
				break;
			case 'post_date':
				$out = $sampleData
					? aioseo()->tags->formatDateAsI18n( date_i18n( 'U' ) )
					: aioseo()->tags->formatDateAsI18n( aioseo()->standalone->buddyPress->component->date );
				break;
			case 'post_day':
				$out = $sampleData
					? date_i18n( 'd' )
					: date( 'd', aioseo()->standalone->buddyPress->component->date );
				break;
			case 'post_month':
				$out = $sampleData
					? date_i18n( 'F' )
					: date( 'F', aioseo()->standalone->buddyPress->component->date );
				break;
			case 'post_year':
				$out = $sampleData
					? date_i18n( 'Y' )
					: date( 'Y', aioseo()->standalone->buddyPress->component->date );
				break;
			case 'archive_title':
				$out = $sampleData
					? __( 'Sample Archive Title', 'all-in-one-seo-pack' )
					: esc_html( get_the_title() );
				break;
			case 'bp_activity_action':
				$out = $sampleData
					? _x( 'Sample Activity Action', 'BuddyPress', 'all-in-one-seo-pack' )
					: aioseo()->standalone->buddyPress->component->activity['action'];
				break;
			case 'bp_activity_content':
				$out = $sampleData
					? _x( 'Sample activity content', 'BuddyPress', 'all-in-one-seo-pack' )
					: aioseo()->standalone->buddyPress->component->activity['content_rendered'];
				break;
			case 'bp_group_name':
				$out = $sampleData
					? _x( 'Sample Group Name', 'BuddyPress', 'all-in-one-seo-pack' )
					: aioseo()->standalone->buddyPress->component->group['name'];
				break;
			case 'bp_group_description':
				$out = $sampleData
					? _x( 'Sample group description', 'BuddyPress', 'all-in-one-seo-pack' )
					: aioseo()->standalone->buddyPress->component->group['description'];
				break;
			case 'bp_group_type_singular_name':
				$out = $sampleData ? _x( 'Sample Type Singular', 'BuddyPress', 'all-in-one-seo-pack' ) : '';
				if ( ! empty( aioseo()->standalone->buddyPress->component->groupType ) ) {
					$out = aioseo()->standalone->buddyPress->component->groupType['singular'];
				}
				break;
			case 'bp_group_type_plural_name':
				$out = $sampleData ? _x( 'Sample Type Plural', 'BuddyPress', 'all-in-one-seo-pack' ) : '';
				if ( ! empty( aioseo()->standalone->buddyPress->component->groupType ) ) {
					$out = aioseo()->standalone->buddyPress->component->groupType['plural'];
				}
				break;
			default:
				$out = aioseo()->tags->getTagValue( $tag, $id );
		}

		return $out ?? '';
	}
}