Skip to content

Commit 48b4cae

Browse files
authored
feat(content-distribution): Block the editor for incoming posts (#181)
* 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
1 parent 120b759 commit 48b4cae

File tree

8 files changed

+420
-29
lines changed

8 files changed

+420
-29
lines changed

includes/content-distribution/class-api.php

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,11 @@
77

88
namespace Newspack_Network\Content_Distribution;
99

10+
use InvalidArgumentException;
1011
use Newspack_Network\Content_Distribution;
1112
use WP_Error;
13+
use WP_REST_Response;
14+
use WP_REST_Server;
1215

1316
/**
1417
* API Class.
@@ -17,14 +20,14 @@ class API {
1720
/**
1821
* Initialize hooks.
1922
*/
20-
public static function init() {
23+
public static function init(): void {
2124
add_action( 'rest_api_init', [ __CLASS__, 'register_routes' ] );
2225
}
2326

2427
/**
2528
* Register the REST API routes.
2629
*/
27-
public static function register_routes() {
30+
public static function register_routes(): void {
2831
register_rest_route(
2932
'newspack-network/v1',
3033
'/content-distribution/distribute/(?P<post_id>\d+)',
@@ -40,27 +43,72 @@ public static function register_routes() {
4043
],
4144
],
4245
],
43-
'permission_callback' => function() {
46+
'permission_callback' => function () {
4447
return current_user_can( Admin::CAPABILITY );
4548
},
4649
]
4750
);
51+
52+
register_rest_route(
53+
'newspack-network/v1',
54+
'/content-distribution/unlink/(?P<post_id>\d+)',
55+
[
56+
'methods' => WP_REST_Server::EDITABLE,
57+
'callback' => [ __CLASS__, 'toggle_unlink' ],
58+
'args' => [
59+
'unlinked' => [
60+
'required' => true,
61+
'type' => 'boolean',
62+
],
63+
],
64+
'permission_callback' => function () {
65+
return current_user_can( Admin::CAPABILITY );
66+
},
67+
]
68+
);
69+
}
70+
71+
/**
72+
* Toggle the unlinked status of an incoming post.
73+
*
74+
* @param \WP_REST_Request $request The REST request object.
75+
*
76+
* @return WP_REST_Response|WP_Error The REST response or error.
77+
*/
78+
public static function toggle_unlink( $request ): WP_REST_Response|WP_Error {
79+
$post_id = $request->get_param( 'post_id' );
80+
$unlinked = $request->get_param( 'unlinked' );
81+
82+
try {
83+
$incoming_post = new Incoming_Post( $post_id );
84+
$incoming_post->set_unlinked( $unlinked );
85+
} catch ( InvalidArgumentException $e ) {
86+
return new WP_Error( 'newspack_network_content_distribution_error', $e->getMessage(), [ 'status' => 400 ] );
87+
}
88+
89+
return rest_ensure_response(
90+
[
91+
'post_id' => $post_id,
92+
'unlinked' => ! $incoming_post->is_linked(),
93+
'status' => 'success',
94+
]
95+
);
4896
}
4997

5098
/**
5199
* Distribute a post to the network.
52100
*
53101
* @param \WP_REST_Request $request The REST request object.
54102
*
55-
* @return \WP_REST_Response|WP_Error The REST response or error.
103+
* @return WP_REST_Response|WP_Error The REST response or error.
56104
*/
57105
public static function distribute( $request ) {
58106
$post_id = $request->get_param( 'post_id' );
59107
$urls = $request->get_param( 'urls' );
60108

61109
try {
62110
$outgoing_post = new Outgoing_Post( $post_id );
63-
} catch ( \InvalidArgumentException $e ) {
111+
} catch ( InvalidArgumentException $e ) {
64112
return new WP_Error( 'newspack_network_content_distribution_error', $e->getMessage(), [ 'status' => 400 ] );
65113
}
66114

includes/content-distribution/class-editor.php

Lines changed: 58 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
use Newspack_Network\Content_Distribution;
1111
use Newspack_Network\Utils\Network;
12+
use WP_Post;
1213

1314
/**
1415
* Editor Class.
@@ -47,7 +48,7 @@ public static function register_meta() {
4748
],
4849
],
4950
],
50-
'auth_callback' => function() {
51+
'auth_callback' => function () {
5152
return current_user_can( Admin::CAPABILITY );
5253
},
5354
]
@@ -56,27 +57,73 @@ public static function register_meta() {
5657
}
5758

5859
/**
59-
* Enqueue block editor assets.
60+
* Action callback.
6061
*
6162
* @return void
6263
*/
63-
public static function enqueue_block_editor_assets() {
64+
public static function enqueue_block_editor_assets(): void {
6465
$screen = get_current_screen();
65-
if ( ! in_array( $screen->post_type, Content_Distribution::get_distributed_post_types(), true ) ) {
66-
return;
67-
}
68-
69-
if ( ! current_user_can( Admin::CAPABILITY ) ) {
66+
if (
67+
! current_user_can( Admin::CAPABILITY )
68+
|| ! in_array( $screen->post_type, Content_Distribution::get_distributed_post_types(), true )
69+
) {
7070
return;
7171
}
7272

7373
$post = get_post();
7474

75-
// Don't enqueue the script for incoming posts.
7675
if ( Content_Distribution::is_post_incoming( $post ) ) {
77-
return;
76+
self::enqueue_block_editor_assets_for_incoming_post( $post );
77+
} else {
78+
self::enqueue_block_editor_assets_for_outgoing_post( $post );
7879
}
80+
}
81+
82+
/**
83+
* Enqueue block editor assets.
84+
*
85+
* @param WP_Post $post The post being edited.
86+
*
87+
* @return void
88+
*/
89+
private static function enqueue_block_editor_assets_for_incoming_post( WP_Post $post ): void {
90+
91+
$incoming = new Incoming_Post( $post->ID );
92+
93+
wp_enqueue_script(
94+
'newspack-network-incoming-post',
95+
plugins_url( '../../dist/incoming-post.js', __FILE__ ),
96+
[],
97+
filemtime( NEWSPACK_NETWORK_PLUGIN_DIR . 'dist/incoming-post.js' ),
98+
true
99+
);
100+
wp_register_style(
101+
'newspack-network-incoming-post',
102+
plugins_url( '../../dist/incoming-post.css', __FILE__ ),
103+
[],
104+
filemtime( NEWSPACK_NETWORK_PLUGIN_DIR . 'dist/incoming-post.css' ),
105+
);
106+
wp_style_add_data( 'newspack-network-incoming-post', 'rtl', 'replace' );
107+
wp_enqueue_style( 'newspack-network-incoming-post' );
108+
109+
wp_localize_script(
110+
'newspack-network-incoming-post',
111+
'newspack_network_incoming_post',
112+
[
113+
'originalUrl' => $incoming->get_original_site_url(),
114+
'unlinked' => ! $incoming->is_linked(),
115+
]
116+
);
117+
}
79118

119+
/**
120+
* Enqueue block editor assets.
121+
*
122+
* @param WP_Post $post The post being edited.
123+
*
124+
* @return void
125+
*/
126+
private static function enqueue_block_editor_assets_for_outgoing_post( WP_Post $post ): void {
80127
wp_enqueue_script(
81128
'newspack-network-distribute',
82129
plugins_url( '../../dist/distribute.js', __FILE__ ),
@@ -99,7 +146,7 @@ public static function enqueue_block_editor_assets() {
99146
[
100147
'network_sites' => Network::get_networked_urls(),
101148
'distributed_meta' => Outgoing_Post::DISTRIBUTED_POST_META,
102-
'post_type_label' => get_post_type_labels( get_post_type_object( $screen->post_type ) )->singular_name,
149+
'post_type_label' => get_post_type_labels( get_post_type_object( $post->post_type ) )->singular_name,
103150
]
104151
);
105152
}

includes/content-distribution/class-incoming-post.php

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -156,21 +156,21 @@ protected function get_post_payload() {
156156
}
157157

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

167167
/**
168-
* Get the post original site URL.
168+
* Get the post original URL.
169169
*
170-
* @return string The post original site URL. Empty string if not found.
170+
* @return string The post original post URL. Empty string if not found.
171171
*/
172-
public function get_original_site_url() {
173-
return $this->payload['site_url'] ?? '';
172+
public function get_original_post_url() {
173+
return $this->payload['post_url'] ?? '';
174174
}
175175

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

226226
// If the post is being re-linked, update content.
227227
if ( ! $unlinked ) {
@@ -234,8 +234,8 @@ public function set_unlinked( $unlinked = true ) {
234234
*
235235
* @return bool
236236
*/
237-
protected function is_unlinked() {
238-
return get_post_meta( $this->ID, self::UNLINKED_META, true );
237+
protected function is_unlinked(): bool {
238+
return (bool) get_post_meta( $this->ID, self::UNLINKED_META, true );
239239
}
240240

241241
/**
@@ -245,7 +245,7 @@ protected function is_unlinked() {
245245
*
246246
* @return bool
247247
*/
248-
public function is_linked() {
248+
public function is_linked(): bool {
249249
return $this->ID && ! $this->is_unlinked();
250250
}
251251

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/**
2+
* WordPress dependencies.
3+
*/
4+
import { __ } from '@wordpress/i18n';
5+
import { PluginSidebar } from '@wordpress/editor';
6+
import { Flex, Panel, PanelBody } from '@wordpress/components';
7+
import { globe } from '@wordpress/icons';
8+
9+
/**
10+
* Internal dependencies.
11+
*/
12+
import './style.scss';
13+
14+
const ContentDistributionPanel = ({ header, body, footer, buttons }) => {
15+
return (
16+
<PluginSidebar
17+
name="newspack-network-content-distribution-panel"
18+
icon={ globe }
19+
title={ __( 'Distribute', 'newspack-network' ) }
20+
className="newspack-network-content-distribution-panel"
21+
>
22+
<Panel>
23+
<PanelBody className="content-distribution-panel-header">
24+
{ header }
25+
</PanelBody>
26+
<PanelBody className="content-distribution-panel-body">
27+
{ body }
28+
</PanelBody>
29+
<PanelBody className="content-distribution-panel-footer">
30+
{ footer }
31+
<Flex direction="column" className="content-distribution-panel__button-column" gap={ 4 }>
32+
{ buttons }
33+
</Flex>
34+
</PanelBody>
35+
</Panel>
36+
</PluginSidebar>
37+
);
38+
};
39+
40+
export default ContentDistributionPanel;
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
.newspack-network-content-distribution-panel {
2+
height: calc(100% - 47px);
3+
4+
.components-panel {
5+
height: 100%;
6+
display: flex;
7+
flex-direction: column;
8+
}
9+
10+
.components-panel__body {
11+
border: 0;
12+
}
13+
14+
.content-distribution-panel-body {
15+
flex: 1 1 100%;
16+
overflow-y: auto;
17+
padding-top: 0;
18+
19+
}
20+
21+
.content-distribution-panel__button-column {
22+
.components-button {
23+
justify-content: center;
24+
}
25+
}
26+
}

0 commit comments

Comments
 (0)