Skip to content

Commit

Permalink
feat(content-distribution): Block the editor for incoming posts (#181)
Browse files Browse the repository at this point in the history
* feat(content-distribution): Blcok editor for incoming posts

* Work in progress

* Add buttons and a bunch more logic

* phpcs and remove unused meta register

* Better "wait" for sidebar open

* Add busy state to button

* Reload page on relink

* Rename component and fix up CSS a bit
  • Loading branch information
naxoc authored Jan 20, 2025
1 parent 120b759 commit 48b4cae
Show file tree
Hide file tree
Showing 8 changed files with 420 additions and 29 deletions.
58 changes: 53 additions & 5 deletions includes/content-distribution/class-api.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@

namespace Newspack_Network\Content_Distribution;

use InvalidArgumentException;
use Newspack_Network\Content_Distribution;
use WP_Error;
use WP_REST_Response;
use WP_REST_Server;

/**
* API Class.
Expand All @@ -17,14 +20,14 @@ class API {
/**
* Initialize hooks.
*/
public static function init() {
public static function init(): void {
add_action( 'rest_api_init', [ __CLASS__, 'register_routes' ] );
}

/**
* Register the REST API routes.
*/
public static function register_routes() {
public static function register_routes(): void {
register_rest_route(
'newspack-network/v1',
'/content-distribution/distribute/(?P<post_id>\d+)',
Expand All @@ -40,27 +43,72 @@ public static function register_routes() {
],
],
],
'permission_callback' => function() {
'permission_callback' => function () {
return current_user_can( Admin::CAPABILITY );
},
]
);

register_rest_route(
'newspack-network/v1',
'/content-distribution/unlink/(?P<post_id>\d+)',
[
'methods' => WP_REST_Server::EDITABLE,
'callback' => [ __CLASS__, 'toggle_unlink' ],
'args' => [
'unlinked' => [
'required' => true,
'type' => 'boolean',
],
],
'permission_callback' => function () {
return current_user_can( Admin::CAPABILITY );
},
]
);
}

/**
* Toggle the unlinked status of an incoming post.
*
* @param \WP_REST_Request $request The REST request object.
*
* @return WP_REST_Response|WP_Error The REST response or error.
*/
public static function toggle_unlink( $request ): WP_REST_Response|WP_Error {
$post_id = $request->get_param( 'post_id' );
$unlinked = $request->get_param( 'unlinked' );

try {
$incoming_post = new Incoming_Post( $post_id );
$incoming_post->set_unlinked( $unlinked );
} catch ( InvalidArgumentException $e ) {
return new WP_Error( 'newspack_network_content_distribution_error', $e->getMessage(), [ 'status' => 400 ] );
}

return rest_ensure_response(
[
'post_id' => $post_id,
'unlinked' => ! $incoming_post->is_linked(),
'status' => 'success',
]
);
}

/**
* Distribute a post to the network.
*
* @param \WP_REST_Request $request The REST request object.
*
* @return \WP_REST_Response|WP_Error The REST response or error.
* @return WP_REST_Response|WP_Error The REST response or error.
*/
public static function distribute( $request ) {
$post_id = $request->get_param( 'post_id' );
$urls = $request->get_param( 'urls' );

try {
$outgoing_post = new Outgoing_Post( $post_id );
} catch ( \InvalidArgumentException $e ) {
} catch ( InvalidArgumentException $e ) {
return new WP_Error( 'newspack_network_content_distribution_error', $e->getMessage(), [ 'status' => 400 ] );
}

Expand Down
69 changes: 58 additions & 11 deletions includes/content-distribution/class-editor.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

use Newspack_Network\Content_Distribution;
use Newspack_Network\Utils\Network;
use WP_Post;

/**
* Editor Class.
Expand Down Expand Up @@ -47,7 +48,7 @@ public static function register_meta() {
],
],
],
'auth_callback' => function() {
'auth_callback' => function () {
return current_user_can( Admin::CAPABILITY );
},
]
Expand All @@ -56,27 +57,73 @@ public static function register_meta() {
}

/**
* Enqueue block editor assets.
* Action callback.
*
* @return void
*/
public static function enqueue_block_editor_assets() {
public static function enqueue_block_editor_assets(): void {
$screen = get_current_screen();
if ( ! in_array( $screen->post_type, Content_Distribution::get_distributed_post_types(), true ) ) {
return;
}

if ( ! current_user_can( Admin::CAPABILITY ) ) {
if (
! current_user_can( Admin::CAPABILITY )
|| ! in_array( $screen->post_type, Content_Distribution::get_distributed_post_types(), true )
) {
return;
}

$post = get_post();

// Don't enqueue the script for incoming posts.
if ( Content_Distribution::is_post_incoming( $post ) ) {
return;
self::enqueue_block_editor_assets_for_incoming_post( $post );
} else {
self::enqueue_block_editor_assets_for_outgoing_post( $post );
}
}

/**
* Enqueue block editor assets.
*
* @param WP_Post $post The post being edited.
*
* @return void
*/
private static function enqueue_block_editor_assets_for_incoming_post( WP_Post $post ): void {

$incoming = new Incoming_Post( $post->ID );

wp_enqueue_script(
'newspack-network-incoming-post',
plugins_url( '../../dist/incoming-post.js', __FILE__ ),
[],
filemtime( NEWSPACK_NETWORK_PLUGIN_DIR . 'dist/incoming-post.js' ),
true
);
wp_register_style(
'newspack-network-incoming-post',
plugins_url( '../../dist/incoming-post.css', __FILE__ ),
[],
filemtime( NEWSPACK_NETWORK_PLUGIN_DIR . 'dist/incoming-post.css' ),
);
wp_style_add_data( 'newspack-network-incoming-post', 'rtl', 'replace' );
wp_enqueue_style( 'newspack-network-incoming-post' );

wp_localize_script(
'newspack-network-incoming-post',
'newspack_network_incoming_post',
[
'originalUrl' => $incoming->get_original_site_url(),
'unlinked' => ! $incoming->is_linked(),
]
);
}

/**
* Enqueue block editor assets.
*
* @param WP_Post $post The post being edited.
*
* @return void
*/
private static function enqueue_block_editor_assets_for_outgoing_post( WP_Post $post ): void {
wp_enqueue_script(
'newspack-network-distribute',
plugins_url( '../../dist/distribute.js', __FILE__ ),
Expand All @@ -99,7 +146,7 @@ public static function enqueue_block_editor_assets() {
[
'network_sites' => Network::get_networked_urls(),
'distributed_meta' => Outgoing_Post::DISTRIBUTED_POST_META,
'post_type_label' => get_post_type_labels( get_post_type_object( $screen->post_type ) )->singular_name,
'post_type_label' => get_post_type_labels( get_post_type_object( $post->post_type ) )->singular_name,
]
);
}
Expand Down
24 changes: 12 additions & 12 deletions includes/content-distribution/class-incoming-post.php
Original file line number Diff line number Diff line change
Expand Up @@ -156,21 +156,21 @@ protected function get_post_payload() {
}

/**
* Get the post original URL.
* Get the post's original site URL.
*
* @return string The post original post URL. Empty string if not found.
* @return string The post original site URL or an empty string if not found.
*/
public function get_original_post_url() {
return $this->payload['post_url'] ?? '';
public function get_original_site_url(): string {
return $this->payload['site_url'] ?? '';
}

/**
* Get the post original site URL.
* Get the post original URL.
*
* @return string The post original site URL. Empty string if not found.
* @return string The post original post URL. Empty string if not found.
*/
public function get_original_site_url() {
return $this->payload['site_url'] ?? '';
public function get_original_post_url() {
return $this->payload['post_url'] ?? '';
}

/**
Expand Down Expand Up @@ -221,7 +221,7 @@ public function set_unlinked( $unlinked = true ) {
if ( ! $this->ID ) {
return new WP_Error( 'invalid_post', __( 'Invalid post.', 'newspack-network' ) );
}
update_post_meta( $this->ID, self::UNLINKED_META, (bool) $unlinked );
update_post_meta( $this->ID, self::UNLINKED_META, $unlinked ? 1 : 0 );

// If the post is being re-linked, update content.
if ( ! $unlinked ) {
Expand All @@ -234,8 +234,8 @@ public function set_unlinked( $unlinked = true ) {
*
* @return bool
*/
protected function is_unlinked() {
return get_post_meta( $this->ID, self::UNLINKED_META, true );
protected function is_unlinked(): bool {
return (bool) get_post_meta( $this->ID, self::UNLINKED_META, true );
}

/**
Expand All @@ -245,7 +245,7 @@ protected function is_unlinked() {
*
* @return bool
*/
public function is_linked() {
public function is_linked(): bool {
return $this->ID && ! $this->is_unlinked();
}

Expand Down
40 changes: 40 additions & 0 deletions src/content-distribution/content-distribution-panel/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* WordPress dependencies.
*/
import { __ } from '@wordpress/i18n';
import { PluginSidebar } from '@wordpress/editor';
import { Flex, Panel, PanelBody } from '@wordpress/components';
import { globe } from '@wordpress/icons';

/**
* Internal dependencies.
*/
import './style.scss';

const ContentDistributionPanel = ({ header, body, footer, buttons }) => {
return (
<PluginSidebar
name="newspack-network-content-distribution-panel"
icon={ globe }
title={ __( 'Distribute', 'newspack-network' ) }
className="newspack-network-content-distribution-panel"
>
<Panel>
<PanelBody className="content-distribution-panel-header">
{ header }
</PanelBody>
<PanelBody className="content-distribution-panel-body">
{ body }
</PanelBody>
<PanelBody className="content-distribution-panel-footer">
{ footer }
<Flex direction="column" className="content-distribution-panel__button-column" gap={ 4 }>
{ buttons }
</Flex>
</PanelBody>
</Panel>
</PluginSidebar>
);
};

export default ContentDistributionPanel;
26 changes: 26 additions & 0 deletions src/content-distribution/content-distribution-panel/style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
.newspack-network-content-distribution-panel {
height: calc(100% - 47px);

.components-panel {
height: 100%;
display: flex;
flex-direction: column;
}

.components-panel__body {
border: 0;
}

.content-distribution-panel-body {
flex: 1 1 100%;
overflow-y: auto;
padding-top: 0;

}

.content-distribution-panel__button-column {
.components-button {
justify-content: center;
}
}
}
Loading

0 comments on commit 48b4cae

Please sign in to comment.