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

Add "visibility" feature #931

Open
wants to merge 11 commits into
base: trunk
Choose a base branch
from
6 changes: 6 additions & 0 deletions activitypub.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@
\defined( 'ACTIVITYPUB_SEND_VARY_HEADER' ) || \define( 'ACTIVITYPUB_SEND_VARY_HEADER', false );
\defined( 'ACTIVITYPUB_DEFAULT_OBJECT_TYPE' ) || \define( 'ACTIVITYPUB_DEFAULT_OBJECT_TYPE', 'note' );

// Post visibility constants.
\define( 'ACTIVITYPUB_POST_VISIBILITY_PUBLIC', 'public' );
\define( 'ACTIVITYPUB_POST_VISIBILITY_QUIET_PUBLIC', 'quiet_public' );
\define( 'ACTIVITYPUB_POST_VISIBILITY_LOCAL', 'local' );

// Plugin related constants.
\define( 'ACTIVITYPUB_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
\define( 'ACTIVITYPUB_PLUGIN_BASENAME', plugin_basename( __FILE__ ) );
\define( 'ACTIVITYPUB_PLUGIN_FILE', plugin_dir_path( __FILE__ ) . '/' . basename( __FILE__ ) );
Expand Down
2 changes: 1 addition & 1 deletion build/editor-plugin/plugin.asset.php
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<?php return array('dependencies' => array('react', 'wp-components', 'wp-core-data', 'wp-data', 'wp-editor', 'wp-i18n', 'wp-plugins'), 'version' => '88603987940fec29730d');
<?php return array('dependencies' => array('react', 'wp-components', 'wp-core-data', 'wp-data', 'wp-editor', 'wp-element', 'wp-i18n', 'wp-plugins', 'wp-primitives'), 'version' => 'df1915a4380fd2b2c441');
2 changes: 1 addition & 1 deletion build/editor-plugin/plugin.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 14 additions & 2 deletions includes/class-activity-dispatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -269,8 +269,20 @@ public static function add_inboxes_of_follower( $inboxes, $user_id ) {
*/
public static function add_inboxes_by_mentioned_actors( $inboxes, $user_id, $activity ) {
$cc = $activity->get_cc();
if ( $cc ) {
$mentioned_inboxes = Mention::get_inboxes( $cc );
$to = $activity->get_to();

$audience = array_merge( $cc, $to );

// Remove "public placeholder" and "same domain" from the audience.
$audience = array_filter(
$audience,
function ( $actor ) {
return 'https://www.w3.org/ns/activitystreams#Public' !== $actor && ! is_same_domain( $actor );
}
);

if ( $audience ) {
$mentioned_inboxes = Mention::get_inboxes( $audience );

return array_merge( $inboxes, $mentioned_inboxes );
}
Expand Down
2 changes: 1 addition & 1 deletion includes/class-activitypub.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ public static function render_json_template( $template ) {
$json_template = ACTIVITYPUB_PLUGIN_DIR . '/templates/user-json.php';
} elseif ( is_comment() ) {
$json_template = ACTIVITYPUB_PLUGIN_DIR . '/templates/comment-json.php';
} elseif ( \is_singular() ) {
} elseif ( \is_singular() && ! is_post_disabled( \get_the_ID() ) ) {
$json_template = ACTIVITYPUB_PLUGIN_DIR . '/templates/post-json.php';
} elseif ( \is_home() && ! is_user_type_disabled( 'blog' ) ) {
$json_template = ACTIVITYPUB_PLUGIN_DIR . '/templates/blog-json.php';
Expand Down
10 changes: 10 additions & 0 deletions includes/class-blocks.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,16 @@ public static function register_postmeta() {
'sanitize_callback' => 'sanitize_text_field',
)
);
\register_post_meta(
$post_type,
'activitypub_content_visibility',
array(
'show_in_rest' => true,
'single' => true,
'type' => 'string',
'sanitize_callback' => 'sanitize_text_field',
pfefferle marked this conversation as resolved.
Show resolved Hide resolved
)
);
}
}

Expand Down
2 changes: 1 addition & 1 deletion includes/class-scheduler.php
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ public static function deregister_schedules() {
public static function schedule_post_activity( $new_status, $old_status, $post ) {
$post = get_post( $post );

if ( ! $post ) {
if ( ! $post || is_post_disabled( $post ) ) {
return;
}

Expand Down
46 changes: 46 additions & 0 deletions includes/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,31 @@ function is_activitypub_request() {
return false;
}

/**
* Check if a post is disabled for ActivityPub.
*
* @param mixed $post The post object or ID.
*
* @return boolean True if the post is disabled, false otherwise.
*/
function is_post_disabled( $post ) {
$post = \get_post( $post );
$return = false;
pfefferle marked this conversation as resolved.
Show resolved Hide resolved
$visibility = \get_post_meta( $post->ID, 'activitypub_content_visibility', true );

if ( ACTIVITYPUB_POST_VISIBILITY_LOCAL === $visibility ) {
$return = true;
}

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

/**
* This function checks if a user is disabled for ActivityPub.
*
Expand Down Expand Up @@ -1307,3 +1332,24 @@ function get_content_warning( $post_id ) {

return $warning;
}

/**
* Check if a URL is from the same domain as the site.
*
* @param string $url The URL to check.
*
* @return boolean True if the URL is from the same domain, false otherwise.
*/
function is_same_domain( $url ) {
$remote = \wp_parse_url( $url, PHP_URL_HOST );

if ( ! $remote ) {
return false;
}

$remote = normalize_host( $remote );
$self = \wp_parse_url( \home_url(), PHP_URL_HOST );
$self = normalize_host( $self );

return $remote === $self;
}
37 changes: 22 additions & 15 deletions includes/transformer/class-post.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@ public function to_object() {
$object->set_summary_map( null );
}

// Change order if visibility is "Quiet public".
if ( ACTIVITYPUB_POST_VISIBILITY_QUIET_PUBLIC === \get_post_meta( $post->ID, 'activitypub_content_visibility', true ) ) {
$object->set_to( $this->get_cc() );
$object->set_cc( $this->get_to() );
}

return $object;
}

Expand Down Expand Up @@ -680,6 +686,19 @@ protected function get_type() {
return $object_type;
}

/**
* Returns the recipient of the post.
*
* @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-to
*
* @return array The recipient URLs of the post.
*/
public function get_to() {
return array(
'https://www.w3.org/ns/activitystreams#Public',
);
}

/**
* Returns a list of Mentions, used in the Post.
*
Expand All @@ -688,7 +707,9 @@ protected function get_type() {
* @return array The list of Mentions.
*/
protected function get_cc() {
$cc = array();
$cc = array(
$this->get_actor_object()->get_followers(),
);

$mentions = $this->get_mentions();
if ( $mentions ) {
Expand Down Expand Up @@ -946,20 +967,6 @@ public function get_in_reply_to() {
return null;
}

/**
* Returns the recipient of the post.
*
* @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-to
*
* @return array The recipient URLs of the post.
*/
public function get_to() {
return array(
'https://www.w3.org/ns/activitystreams#Public',
$this->get_actor_object()->get_followers(),
);
}

/**
* Returns the published date of the post.
*
Expand Down
2 changes: 1 addition & 1 deletion src/editor-plugin/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@
"keywords": [
],
"editorScript": "file:./plugin.js"
}
}
37 changes: 34 additions & 3 deletions src/editor-plugin/plugin.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { PluginDocumentSettingPanel } from '@wordpress/editor';
import { registerPlugin } from '@wordpress/plugins';
import { TextControl } from '@wordpress/components';
import { TextControl, RadioControl, __experimentalText as Text } from '@wordpress/components';
import { Icon, notAllowed, globe, unseen } from '@wordpress/icons';
import { useSelect } from '@wordpress/data';
import { useEntityProp } from '@wordpress/core-data';
import { __ } from '@wordpress/i18n';
Expand All @@ -13,10 +14,26 @@ const EditorPlugin = () => {
);
const [ meta, setMeta ] = useEntityProp( 'postType', postType, 'meta' );

const labelStyling = {
verticalAlign: "middle",
gap: "4px",
justifyContent:
"start", display:
"inline-flex",
alignItems: "center"
}

const labelWithIcon = ( text, icon ) => (
<Text style={labelStyling}>
<Icon icon={ icon } />
{text}
</Text>
);

return (
<PluginDocumentSettingPanel
name="activitypub"
title={ __( 'Fediverse', 'activitypub' ) }
title={ __( 'Fediverse', 'activitypub' ) }
pfefferle marked this conversation as resolved.
Show resolved Hide resolved
>
<TextControl
label={ __( 'Content Warning', 'activitypub' ) }
Expand All @@ -26,8 +43,22 @@ const EditorPlugin = () => {
} }
placeholder={ __( 'Optional content warning', 'activitypub' ) }
/>
<RadioControl
label={ __( 'Visibility', 'activitypub' ) }
help={ __( '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' ) }
selected={ meta.activitypub_content_visibility ? meta.activitypub_content_visibility : 'public' }
options={ [
{ label: labelWithIcon( __( 'Public', 'activitypub' ), globe ), value: 'public' },
{ label: labelWithIcon( __( 'Quiet public', 'activitypub' ), unseen ), value: 'quiet_public' },
{ label: labelWithIcon( __( 'Do not federate', 'activitypub' ), notAllowed ), value: 'local' },
] }
onChange={ ( value ) => {
setMeta( { ...meta, activitypub_content_visibility: value } );
} }
className="activitypub-visibility"
/>
</PluginDocumentSettingPanel>
);
}

registerPlugin( 'activitypub-editor-plugin', { render: EditorPlugin } );
registerPlugin( 'activitypub-editor-plugin', { render: EditorPlugin } );
2 changes: 1 addition & 1 deletion tests/test-class-activitypub-activity.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ function ( $mentions ) {
$activitypub_activity->set_type( 'Create' );
$activitypub_activity->set_object( $activitypub_post );

$this->assertContains( \Activitypub\get_rest_url_by_path( 'actors/1/followers' ), $activitypub_activity->get_to() );
$this->assertContains( \Activitypub\get_rest_url_by_path( 'actors/1/followers' ), $activitypub_activity->get_cc() );
$this->assertContains( 'https://example.com/alex', $activitypub_activity->get_cc() );

remove_all_filters( 'activitypub_extract_mentions' );
Expand Down
Loading