updated plugin ActivityPub version 8.3.0
This commit is contained in:
@ -0,0 +1,305 @@
|
||||
<?php
|
||||
/**
|
||||
* Classic Editor integration file.
|
||||
*
|
||||
* @package Activitypub
|
||||
*/
|
||||
|
||||
namespace Activitypub\Integration;
|
||||
|
||||
/**
|
||||
* Classic Editor integration class.
|
||||
*
|
||||
* Handles compatibility with the Classic Editor plugin and sites without block editor support.
|
||||
*/
|
||||
class Classic_Editor {
|
||||
|
||||
/**
|
||||
* Initialize the class, registering WordPress hooks.
|
||||
*/
|
||||
public static function init() {
|
||||
\add_filter( 'activitypub_attachments_media_markup', array( self::class, 'filter_attachments_media_markup' ), 10, 2 );
|
||||
\add_filter( 'activitypub_attachment_ids', array( self::class, 'filter_attached_media_ids' ), 10, 2 );
|
||||
\add_action( 'add_meta_boxes', array( self::class, 'add_meta_box' ) );
|
||||
\add_action( 'save_post', array( self::class, 'save_meta_data' ) );
|
||||
|
||||
if ( \function_exists( 'classicpress_version' ) ) {
|
||||
\add_filter( 'activitypub_site_supports_blocks', '__return_false' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter attachment media markup to use shortcodes instead of blocks.
|
||||
*
|
||||
* @param string $markup The custom markup. Empty string by default.
|
||||
* @param array $attachment_ids Array of attachment IDs.
|
||||
*
|
||||
* @return string The generated shortcode markup.
|
||||
*/
|
||||
public static function filter_attachments_media_markup( $markup, $attachment_ids ) {
|
||||
if ( empty( $attachment_ids ) ) {
|
||||
return $markup;
|
||||
}
|
||||
|
||||
$type = strtok( \get_post_mime_type( $attachment_ids[0] ), '/' );
|
||||
|
||||
// Single video or audio file: use media shortcode.
|
||||
if ( 1 === \count( $attachment_ids ) && ( 'video' === $type || 'audio' === $type ) ) {
|
||||
return sprintf(
|
||||
'[%1$s src="%2$s"]',
|
||||
\esc_attr( $type ),
|
||||
\esc_url( \wp_get_attachment_url( $attachment_ids[0] ) )
|
||||
);
|
||||
}
|
||||
|
||||
// Multiple attachments or images: use gallery shortcode.
|
||||
return '[gallery ids="' . implode( ',', $attachment_ids ) . '" link="none"]';
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter to add attached media IDs from the post's media library.
|
||||
*
|
||||
* Returns additional image attachments from the post's media library,
|
||||
* respecting the maximum image attachment limit. Only returns new
|
||||
* attachments that can be added without exceeding the limit.
|
||||
*
|
||||
* @param array $attachments The current list of attachments.
|
||||
* @param \WP_Post $item The post item.
|
||||
*
|
||||
* @return array Array of new media IDs to add (as associative arrays with 'id' key).
|
||||
* Returns empty array if already at or over the limit.
|
||||
*/
|
||||
public static function filter_attached_media_ids( $attachments, $item ) {
|
||||
$max_media = \get_option( 'activitypub_max_image_attachments', \ACTIVITYPUB_MAX_IMAGE_ATTACHMENTS );
|
||||
$actual_count = \max( 0, $max_media - \count( $attachments ) );
|
||||
|
||||
if ( $actual_count <= 0 ) {
|
||||
return $attachments;
|
||||
}
|
||||
|
||||
$query = new \WP_Query(
|
||||
array(
|
||||
'post_parent' => $item->ID,
|
||||
'post_status' => 'inherit',
|
||||
'post_type' => 'attachment',
|
||||
'post_mime_type' => 'image',
|
||||
'order' => 'ASC',
|
||||
'orderby' => 'menu_order ID',
|
||||
'fields' => 'ids',
|
||||
'posts_per_page' => $actual_count,
|
||||
)
|
||||
);
|
||||
|
||||
// Transform IDs into associative arrays.
|
||||
$media_ids = \array_map(
|
||||
static function ( $id ) {
|
||||
return array( 'id' => $id );
|
||||
},
|
||||
$query->get_posts()
|
||||
);
|
||||
|
||||
return \array_merge( $attachments, $media_ids );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add ActivityPub meta box to the post editor.
|
||||
*
|
||||
* @param string $post_type The post type.
|
||||
*/
|
||||
public static function add_meta_box( $post_type ) {
|
||||
// Only add for post types that support ActivityPub.
|
||||
if ( ! \post_type_supports( $post_type, 'activitypub' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
\add_meta_box(
|
||||
'activitypub-settings',
|
||||
\__( 'Fediverse ⁂', 'activitypub' ),
|
||||
array( self::class, 'render_meta_box' ),
|
||||
$post_type,
|
||||
'side',
|
||||
'default'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the ActivityPub meta box.
|
||||
*
|
||||
* @param \WP_Post $post The post object.
|
||||
*/
|
||||
public static function render_meta_box( $post ) {
|
||||
// Add nonce for security.
|
||||
\wp_nonce_field( 'activitypub_meta_box', 'activitypub_meta_box_nonce' );
|
||||
|
||||
// Get current values.
|
||||
$content_warning = \get_post_meta( $post->ID, 'activitypub_content_warning', true );
|
||||
$max_image_attachments = \get_post_meta( $post->ID, 'activitypub_max_image_attachments', true );
|
||||
$content_visibility = self::get_default_visibility( $post );
|
||||
$default_quote_policy = \get_option( 'activitypub_default_quote_policy', ACTIVITYPUB_INTERACTION_POLICY_ANYONE );
|
||||
$quote_interaction = \get_post_meta( $post->ID, 'activitypub_interaction_policy_quote', true ) ?: $default_quote_policy;
|
||||
|
||||
?>
|
||||
<p>
|
||||
<label for="activitypub_content_warning">
|
||||
<strong><?php \esc_html_e( 'Content Warning', 'activitypub' ); ?></strong>
|
||||
</label><br />
|
||||
<input type="text" id="activitypub_content_warning" name="activitypub_content_warning" value="<?php echo \esc_attr( $content_warning ); ?>" class="widefat" placeholder="<?php \esc_attr_e( 'Optional content warning', 'activitypub' ); ?>" />
|
||||
<span class="howto"><?php \esc_html_e( 'Content warnings do not change the content on your site, only in the fediverse.', 'activitypub' ); ?></span>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<label for="activitypub_max_image_attachments">
|
||||
<strong><?php \esc_html_e( 'Maximum Image Attachments', 'activitypub' ); ?></strong>
|
||||
</label><br />
|
||||
<input type="number" id="activitypub_max_image_attachments" name="activitypub_max_image_attachments" value="<?php echo \esc_attr( $max_image_attachments ); ?>" min="0" max="10" class="small-text" />
|
||||
<span class="howto"><?php \esc_html_e( 'Maximum number of image attachments to include when sharing to the fediverse.', 'activitypub' ); ?></span>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong><?php \esc_html_e( 'Visibility', 'activitypub' ); ?></strong><br />
|
||||
<label>
|
||||
<input type="radio" name="activitypub_content_visibility" value="<?php echo \esc_attr( ACTIVITYPUB_CONTENT_VISIBILITY_PUBLIC ); ?>" <?php \checked( $content_visibility, ACTIVITYPUB_CONTENT_VISIBILITY_PUBLIC ); ?> />
|
||||
<?php \esc_html_e( 'Public', 'activitypub' ); ?>
|
||||
</label><br />
|
||||
<label>
|
||||
<input type="radio" name="activitypub_content_visibility" value="<?php echo \esc_attr( ACTIVITYPUB_CONTENT_VISIBILITY_QUIET_PUBLIC ); ?>" <?php \checked( $content_visibility, ACTIVITYPUB_CONTENT_VISIBILITY_QUIET_PUBLIC ); ?> />
|
||||
<?php \esc_html_e( 'Quiet public', 'activitypub' ); ?>
|
||||
</label><br />
|
||||
<label>
|
||||
<input type="radio" name="activitypub_content_visibility" value="<?php echo \esc_attr( ACTIVITYPUB_CONTENT_VISIBILITY_LOCAL ); ?>" <?php \checked( $content_visibility, ACTIVITYPUB_CONTENT_VISIBILITY_LOCAL ); ?> />
|
||||
<?php \esc_html_e( 'Do not federate', 'activitypub' ); ?>
|
||||
</label><br />
|
||||
<span class="howto"><?php \esc_html_e( 'This adjusts the visibility of a post in the fediverse, but note that it won\'t affect how the post appears on the blog.', 'activitypub' ); ?></span>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<label for="activitypub_interaction_policy_quote">
|
||||
<strong><?php \esc_html_e( 'Who can quote this post?', 'activitypub' ); ?></strong>
|
||||
</label><br />
|
||||
<select id="activitypub_interaction_policy_quote" name="activitypub_interaction_policy_quote" class="widefat">
|
||||
<option value="<?php echo \esc_attr( ACTIVITYPUB_INTERACTION_POLICY_ANYONE ); ?>" <?php \selected( $quote_interaction, ACTIVITYPUB_INTERACTION_POLICY_ANYONE ); ?>><?php \esc_html_e( 'Anyone', 'activitypub' ); ?></option>
|
||||
<option value="<?php echo \esc_attr( ACTIVITYPUB_INTERACTION_POLICY_FOLLOWERS ); ?>" <?php \selected( $quote_interaction, ACTIVITYPUB_INTERACTION_POLICY_FOLLOWERS ); ?>><?php \esc_html_e( 'Followers only', 'activitypub' ); ?></option>
|
||||
<option value="<?php echo \esc_attr( ACTIVITYPUB_INTERACTION_POLICY_ME ); ?>" <?php \selected( $quote_interaction, ACTIVITYPUB_INTERACTION_POLICY_ME ); ?>><?php \esc_html_e( 'Just me', 'activitypub' ); ?></option>
|
||||
</select>
|
||||
<span class="howto">
|
||||
<?php \esc_html_e( 'Quoting allows others to cite your post while adding their own commentary.', 'activitypub' ); ?>
|
||||
<?php
|
||||
printf(
|
||||
/* translators: %s: The current site default quote policy. Note the leading space. */
|
||||
\esc_html__( ' Site default: %s', 'activitypub' ),
|
||||
\esc_html( self::get_quote_policy_label( $default_quote_policy ) )
|
||||
);
|
||||
?>
|
||||
</span>
|
||||
</p>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the label for a quote policy value.
|
||||
*
|
||||
* @param string $policy The policy value.
|
||||
*
|
||||
* @return string The translated label.
|
||||
*/
|
||||
private static function get_quote_policy_label( $policy ) {
|
||||
$labels = array(
|
||||
ACTIVITYPUB_INTERACTION_POLICY_ANYONE => \__( 'Anyone', 'activitypub' ),
|
||||
ACTIVITYPUB_INTERACTION_POLICY_FOLLOWERS => \__( 'Followers only', 'activitypub' ),
|
||||
ACTIVITYPUB_INTERACTION_POLICY_ME => \__( 'Just me', 'activitypub' ),
|
||||
);
|
||||
|
||||
return $labels[ $policy ] ?? $labels[ ACTIVITYPUB_INTERACTION_POLICY_ANYONE ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default visibility based on post age and federation status.
|
||||
*
|
||||
* @param \WP_Post $post The post object.
|
||||
*
|
||||
* @return string The default visibility value.
|
||||
*/
|
||||
private static function get_default_visibility( $post ) {
|
||||
// If already set, use that value.
|
||||
$saved_visibility = \get_post_meta( $post->ID, 'activitypub_content_visibility', true );
|
||||
if ( $saved_visibility ) {
|
||||
return $saved_visibility;
|
||||
}
|
||||
|
||||
// If post is federated, use public.
|
||||
$status = \get_post_meta( $post->ID, 'activitypub_status', true );
|
||||
if ( ACTIVITYPUB_OBJECT_STATE_FEDERATED === $status ) {
|
||||
return ACTIVITYPUB_CONTENT_VISIBILITY_PUBLIC;
|
||||
}
|
||||
|
||||
// If post is older than 1 month, default to local.
|
||||
$post_timestamp = \strtotime( $post->post_date );
|
||||
$one_month_ago = \strtotime( '-30 days' );
|
||||
|
||||
if ( $post_timestamp < $one_month_ago ) {
|
||||
return ACTIVITYPUB_CONTENT_VISIBILITY_LOCAL;
|
||||
}
|
||||
|
||||
// Default to public for new posts.
|
||||
return ACTIVITYPUB_CONTENT_VISIBILITY_PUBLIC;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save ActivityPub meta data.
|
||||
*
|
||||
* @param int $post_id The post ID.
|
||||
*/
|
||||
public static function save_meta_data( $post_id ) {
|
||||
// Check if this is an autosave.
|
||||
if ( \defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Only process for post types that support ActivityPub.
|
||||
if ( ! \post_type_supports( \get_post_type( $post_id ), 'activitypub' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check user permissions.
|
||||
if ( ! \current_user_can( 'edit_post', $post_id ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Verify nonce is present and valid.
|
||||
if ( ! isset( $_POST['activitypub_meta_box_nonce'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! \wp_verify_nonce( \sanitize_text_field( \wp_unslash( $_POST['activitypub_meta_box_nonce'] ) ), 'activitypub_meta_box' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Save content warning.
|
||||
if ( isset( $_POST['activitypub_content_warning'] ) ) {
|
||||
$content_warning = \sanitize_text_field( \wp_unslash( $_POST['activitypub_content_warning'] ) );
|
||||
if ( ! empty( $content_warning ) ) {
|
||||
\update_post_meta( $post_id, 'activitypub_content_warning', $content_warning );
|
||||
} else {
|
||||
\delete_post_meta( $post_id, 'activitypub_content_warning' );
|
||||
}
|
||||
}
|
||||
|
||||
// Save max image attachments.
|
||||
if ( isset( $_POST['activitypub_max_image_attachments'] ) ) {
|
||||
$max_images = \absint( $_POST['activitypub_max_image_attachments'] );
|
||||
\update_post_meta( $post_id, 'activitypub_max_image_attachments', $max_images );
|
||||
}
|
||||
|
||||
// Save content visibility.
|
||||
if ( isset( $_POST['activitypub_content_visibility'] ) ) {
|
||||
$visibility = \sanitize_text_field( \wp_unslash( $_POST['activitypub_content_visibility'] ) );
|
||||
\update_post_meta( $post_id, 'activitypub_content_visibility', $visibility );
|
||||
}
|
||||
|
||||
// Save quote interaction policy.
|
||||
if ( isset( $_POST['activitypub_interaction_policy_quote'] ) ) {
|
||||
$quote_policy = \sanitize_text_field( \wp_unslash( $_POST['activitypub_interaction_policy_quote'] ) );
|
||||
\update_post_meta( $post_id, 'activitypub_interaction_policy_quote', $quote_policy );
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user