mirror of
https://github.com/discourse/wp-discourse.git
synced 2025-10-03 08:59:21 +08:00
DEV: Refactor publish_post_after_save function (#488)
* Refactor publish_post_after_save function * Simplify return statements; move update_post_meta call out of force_publish_post function. * Simplify publish_to_discourse condition; Add tests for the force-publish option. * Use gmdate() instead of date() in force_publish_max_age test. * Add force_publish_allowed method and property; Update unit tests. * Remove type declaration from property. Not suported in < php7.4
This commit is contained in:
parent
7a810ab710
commit
70fbc7ca32
2 changed files with 865 additions and 678 deletions
|
@ -42,6 +42,16 @@ class DiscoursePublish extends DiscourseBase {
|
|||
*/
|
||||
protected $log_args;
|
||||
|
||||
/**
|
||||
* Allows the `force_publish_allowed` method to return `true` in unit tests.
|
||||
*
|
||||
* @access public
|
||||
* @var bool
|
||||
*/
|
||||
public $force_publish_allowed = false;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* DiscoursePublish constructor.
|
||||
*
|
||||
|
@ -69,64 +79,113 @@ class DiscoursePublish extends DiscourseBase {
|
|||
}
|
||||
|
||||
/**
|
||||
* Published a post to Discourse after it has been saved.
|
||||
* Determines if a post should be published to Discourse after it is saved on WordPress.
|
||||
*
|
||||
* @param int $post_id The id of the post that has been saved.
|
||||
* @param object $post The Post object.
|
||||
* @param \WP_Post $post The Post object.
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function publish_post_after_save( $post_id, $post ) {
|
||||
if ( $this->exclude_post( $post_id, $post ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$post_should_be_auto_published = $this->auto_publish( $post_id );
|
||||
$post_already_published = $this->dc_get_post_meta( $post_id, 'discourse_post_id', true );
|
||||
$post_marked_to_be_published = $this->dc_get_post_meta( $post_id, 'publish_to_discourse', true );
|
||||
$publish_new_post_to_discourse = ( $post_marked_to_be_published || $post_should_be_auto_published ) && ! $post_already_published;
|
||||
$topic_should_be_updated = $this->dc_get_post_meta( $post_id, 'update_discourse_topic', true );
|
||||
$force_publish_post = $this->force_publish_post( $post );
|
||||
if ( $force_publish_post ) {
|
||||
// All force published posts are published to the default publish-category.
|
||||
update_post_meta( $post_id, 'publish_post_category', intval( $this->options['publish-category'] ) );
|
||||
}
|
||||
|
||||
$publish_to_discourse = $publish_new_post_to_discourse || $topic_should_be_updated || $force_publish_post;
|
||||
$publish_to_discourse = apply_filters( 'wpdc_publish_after_save', $publish_to_discourse, $post_id, $post );
|
||||
|
||||
if ( $publish_to_discourse ) {
|
||||
$title = $this->sanitize_title( $post->post_title );
|
||||
$title = apply_filters( 'wpdc_publish_format_title', $title, $post_id );
|
||||
// Clear existing publishing errors.
|
||||
delete_post_meta( $post_id, 'wpdc_publishing_error' );
|
||||
$this->sync_to_discourse( $post_id, $title, $post->post_content );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Excludes a post from being published under various conditions.
|
||||
*
|
||||
* Posts are excluded from publishing if the plugin is unconfigured, the post's status is not set to 'publish',
|
||||
* the post is a revision, doesn't have a title, is not a valid post type, or has an excluded tag.
|
||||
*
|
||||
* @param int $post_id The ID of the post.
|
||||
* @param \WP_Post $post The Post object.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function exclude_post( $post_id, $post ) {
|
||||
$plugin_unconfigured = empty( $this->options['url'] ) || empty( $this->options['api-key'] ) || empty( $this->options['publish-username'] );
|
||||
$publish_status_not_set = 'publish' !== get_post_status( $post_id );
|
||||
$publish_private = apply_filters( 'wpdc_publish_private_post', false, $post_id );
|
||||
if ( wp_is_post_revision( $post_id )
|
||||
return wp_is_post_revision( $post_id )
|
||||
|| ( $publish_status_not_set && ! $publish_private )
|
||||
|| $plugin_unconfigured
|
||||
|| empty( $post->post_title )
|
||||
|| ! $this->is_valid_sync_post_type( $post_id )
|
||||
|| $this->has_excluded_tag( $post_id, $post )
|
||||
) {
|
||||
|
||||
return null;
|
||||
|| $this->has_excluded_tag( $post );
|
||||
}
|
||||
|
||||
// Clear existing publishing errors.
|
||||
delete_post_meta( $post_id, 'wpdc_publishing_error' );
|
||||
|
||||
/**
|
||||
* Determines if the plugin's 'auto-publish' option is enabled and if it has been overridden for a particular post.
|
||||
*
|
||||
* The auto-publish option causes the 'Publish to Discourse' checkbox in the post editor to be pre-checked for all new
|
||||
* posts. It is 'overridden' if the checkbox is manually unchecked.
|
||||
*
|
||||
* @param int $post_id The ID of the post.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function auto_publish( $post_id ) {
|
||||
// If the auto-publish option is enabled publish unpublished topics, unless the setting has been overridden.
|
||||
$auto_publish_overridden = intval( get_post_meta( $post_id, 'wpdc_auto_publish_overridden', true ) ) === 1;
|
||||
$auto_publish = ! $auto_publish_overridden && ! empty( $this->options['auto-publish'] );
|
||||
$auto_publish_overridden = intval( $this->dc_get_post_meta( $post_id, 'wpdc_auto_publish_overridden', true ) ) === 1;
|
||||
return ! $auto_publish_overridden && ! empty( $this->options['auto-publish'] );
|
||||
}
|
||||
|
||||
$publish_to_discourse = get_post_meta( $post_id, 'publish_to_discourse', true ) || $auto_publish;
|
||||
$publish_to_discourse = apply_filters( 'wpdc_publish_after_save', $publish_to_discourse, $post_id, $post );
|
||||
/**
|
||||
* Determines if a post should be 'force published.'
|
||||
*
|
||||
* Posts are force published if the 'force-publish' option is enabled and the post was created within the time period
|
||||
* set by the 'force-publish-max-age' setting (ignored when 'force-publish-max-age is set to 0.)
|
||||
*
|
||||
* @param object $post The Post object.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function force_publish_post( $post ) {
|
||||
if ( empty( $this->options['force-publish'] ) || ! $this->force_publish_allowed() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$force_publish_enabled = ! empty( $this->options['force-publish'] );
|
||||
$force_publish_post = false;
|
||||
if ( $force_publish_enabled ) {
|
||||
// The Force Publish setting can't be easily supported with both the Block and Classic editors. The $is_rest_request
|
||||
// variable is used to only allow the Force Publish setting to be respected for posts published with the Block Editor.
|
||||
$is_rest_request = defined( 'REST_REQUEST' ) && REST_REQUEST;
|
||||
$force_publish_max_age = ! empty( $this->options['force-publish-max-age'] ) ? intval( $this->options['force-publish-max-age'] ) : 0;
|
||||
$min_date = date_create()->modify( "-{$force_publish_max_age} day" )->format( 'U' );
|
||||
$post_time = strtotime( $post->post_date );
|
||||
|
||||
if ( ( ( 0 === $force_publish_max_age ) || $post_time >= $min_date ) && $is_rest_request ) {
|
||||
$force_publish_post = true;
|
||||
update_post_meta( $post_id, 'publish_post_category', intval( $this->options['publish-category'] ) );
|
||||
}
|
||||
return 0 === $force_publish_max_age || $post_time >= $min_date;
|
||||
}
|
||||
|
||||
$already_published = $this->dc_get_post_meta( $post_id, 'discourse_post_id', true );
|
||||
$update_discourse_topic = get_post_meta( $post_id, 'update_discourse_topic', true );
|
||||
$title = $this->sanitize_title( $post->post_title );
|
||||
$title = apply_filters( 'wpdc_publish_format_title', $title, $post_id );
|
||||
|
||||
if ( $force_publish_post || ( ! $already_published && $publish_to_discourse ) || $update_discourse_topic ) {
|
||||
$this->sync_to_discourse( $post_id, $title, $post->post_content );
|
||||
}
|
||||
|
||||
return null;
|
||||
/**
|
||||
* Checks if the post was published via REST_REQUEST.
|
||||
*
|
||||
* Currently, the force-publish option is only supported for posts published via the Block editor (a REST_REQUEST.)
|
||||
* The `force_publish_allowed` property is used in unit tests.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function force_publish_allowed() {
|
||||
return ( defined( 'REST_REQUEST' ) && REST_REQUEST ) || $this->force_publish_allowed;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -148,7 +207,7 @@ class DiscoursePublish extends DiscourseBase {
|
|||
$title = $this->sanitize_title( $post->post_title );
|
||||
$title = apply_filters( 'wpdc_publish_format_title', $title, $post_id );
|
||||
|
||||
if ( $publish_to_discourse && $post_is_published && $this->is_valid_sync_post_type( $post_id ) && ! empty( $title ) && ! $this->has_excluded_tag( $post_id ) ) {
|
||||
if ( $publish_to_discourse && $post_is_published && $this->is_valid_sync_post_type( $post_id ) && ! empty( $title ) && ! $this->has_excluded_tag( $post ) ) {
|
||||
update_post_meta( $post_id, 'publish_to_discourse', 1 );
|
||||
$this->sync_to_discourse( $post_id, $title, $post->post_content );
|
||||
} elseif ( $post_is_published && ! empty( $this->options['auto-publish'] ) ) {
|
||||
|
@ -728,12 +787,11 @@ class DiscoursePublish extends DiscourseBase {
|
|||
/**
|
||||
* Checks if a post has an excluded tag.
|
||||
*
|
||||
* @param int $post_id The ID of the post in question.
|
||||
* @param \WP_Post $post The Post object.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function has_excluded_tag( $post_id, $post ) {
|
||||
protected function has_excluded_tag( $post ) {
|
||||
if ( version_compare( get_bloginfo( 'version' ), '5.6', '<' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ use \WPDiscourse\Test\UnitTest;
|
|||
*/
|
||||
class DiscoursePublishTest extends UnitTest {
|
||||
|
||||
|
||||
/**
|
||||
* Instance of DiscoursePublish.
|
||||
*
|
||||
|
@ -31,6 +32,7 @@ class DiscoursePublishTest extends UnitTest {
|
|||
public static function setUpBeforeClass() {
|
||||
parent::setUpBeforeClass();
|
||||
self::initialize_variables();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -671,12 +673,15 @@ class DiscoursePublishTest extends UnitTest {
|
|||
|
||||
// Add filter.
|
||||
add_filter(
|
||||
'wpdc_publish_body', function( $body, $remote_post_type ) use ( $tags ) {
|
||||
'wpdc_publish_body',
|
||||
function( $body, $remote_post_type ) use ( $tags ) {
|
||||
if ( 'create_post' === $remote_post_type ) {
|
||||
$body['tags'] = $tags;
|
||||
}
|
||||
return $body;
|
||||
}, 10, 2
|
||||
},
|
||||
10,
|
||||
2
|
||||
);
|
||||
|
||||
$raw_body = $this->response_body_json( 'post_create' );
|
||||
|
@ -686,7 +691,8 @@ class DiscoursePublishTest extends UnitTest {
|
|||
|
||||
// Check tags are in the body passed to request.
|
||||
add_filter(
|
||||
'pre_http_request', function( $prempt, $args, $url ) use ( $tags, $response ) {
|
||||
'pre_http_request',
|
||||
function( $prempt, $args, $url ) use ( $tags, $response ) {
|
||||
$body = json_decode( $args['body'] );
|
||||
|
||||
if ( ! isset( $body->tags ) || ! ( $tags === $body->tags ) ) {
|
||||
|
@ -694,7 +700,9 @@ class DiscoursePublishTest extends UnitTest {
|
|||
} else {
|
||||
return $response;
|
||||
}
|
||||
}, 10, 3
|
||||
},
|
||||
10,
|
||||
3
|
||||
);
|
||||
|
||||
// Setup post.
|
||||
|
@ -713,6 +721,127 @@ class DiscoursePublishTest extends UnitTest {
|
|||
wp_delete_post( $post_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the default value of the force_publish_allowed property prevents force-publishing.
|
||||
*/
|
||||
public function test_force_publish_allowed_property() {
|
||||
// Enable the force-publish option, but don't override default value of the force_publish_allowed property.
|
||||
self::$plugin_options['force-publish'] = 1;
|
||||
$this->publish->setup_options( self::$plugin_options );
|
||||
|
||||
// Set up a response body for creating a new post.
|
||||
$body = $this->mock_remote_post_success( 'post_create', 'POST' );
|
||||
$discourse_post_id = $body->id;
|
||||
|
||||
// Set publish_to_discourse to 0 to test the force-publish option.
|
||||
$post_atts = self::$post_atts;
|
||||
$post_atts['meta_input']['publish_to_discourse'] = 0;
|
||||
$post_id = wp_insert_post( $post_atts, false, false );
|
||||
|
||||
// Trigger the publish_post_after_save method.
|
||||
$post = get_post( $post_id );
|
||||
$this->publish->publish_post_after_save( $post_id, $post );
|
||||
|
||||
// Ensure that publication has not occurred.
|
||||
$this->assertEmpty( get_post_meta( $post_id, 'discourse_post_id', true ) );
|
||||
|
||||
// Set force_publish_allowed to true.
|
||||
$this->publish->force_publish_allowed = true;
|
||||
|
||||
// Trigger the publish_post_after_save method.
|
||||
$this->publish->publish_post_after_save( $post_id, $post );
|
||||
|
||||
// Ensure that publication has occurred.
|
||||
$this->assertEquals( get_post_meta( $post_id, 'discourse_post_id', true ), $discourse_post_id );
|
||||
$this->assertEquals( get_post_meta( $post_id, 'wpdc_publishing_response', true ), 'success' );
|
||||
|
||||
// Cleanup.
|
||||
wp_delete_post( $post_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that enabling the force-publish overrides the publish_to_discourse meta-data.
|
||||
*/
|
||||
public function test_force_publish_option() {
|
||||
$this->publish->force_publish_allowed = true;
|
||||
// Explicitly disable the force-publish option.
|
||||
self::$plugin_options['force-publish'] = 0;
|
||||
$this->publish->setup_options( self::$plugin_options );
|
||||
|
||||
// Set up a response body for creating a new post.
|
||||
$body = $this->mock_remote_post_success( 'post_create', 'POST' );
|
||||
$discourse_post_id = $body->id;
|
||||
|
||||
// Set publish_to_discourse to 0 to test the force-publish option.
|
||||
$post_atts = self::$post_atts;
|
||||
$post_atts['meta_input']['publish_to_discourse'] = 0;
|
||||
$post_id = wp_insert_post( $post_atts, false, false );
|
||||
|
||||
// Trigger the publish_post_after_save method.
|
||||
$post = get_post( $post_id );
|
||||
$this->publish->publish_post_after_save( $post_id, $post );
|
||||
|
||||
// Ensure that publication has not occurred.
|
||||
$this->assertEmpty( get_post_meta( $post_id, 'discourse_post_id', true ) );
|
||||
|
||||
// Enable the force-publish option.
|
||||
self::$plugin_options['force-publish'] = 1;
|
||||
$this->publish->setup_options( self::$plugin_options );
|
||||
|
||||
// Trigger the publish_post_after_save method.
|
||||
$this->publish->publish_post_after_save( $post_id, $post );
|
||||
|
||||
// Ensure that publication has occurred.
|
||||
$this->assertEquals( get_post_meta( $post_id, 'discourse_post_id', true ), $discourse_post_id );
|
||||
$this->assertEquals( get_post_meta( $post_id, 'wpdc_publishing_response', true ), 'success' );
|
||||
|
||||
// Cleanup.
|
||||
wp_delete_post( $post_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the force-publish-max-age option prevents older posts from being published.
|
||||
*/
|
||||
public function test_force_publish_max_age_prevents_older_posts_from_being_published() {
|
||||
$this->publish->force_publish_allowed = true;
|
||||
self::$plugin_options['force-publish'] = 1;
|
||||
// Don't publish posts that were created greater than 2 days ago.
|
||||
self::$plugin_options['force-publish-max-age'] = 2;
|
||||
$this->publish->setup_options( self::$plugin_options );
|
||||
|
||||
// Set up a response hook for creating a new post.
|
||||
$body = $this->mock_remote_post_success( 'post_create', 'POST' );
|
||||
$discourse_post_id = $body->id;
|
||||
|
||||
// Set publish_to_discourse to 0 to test the force-publish option.
|
||||
// Set post_date to 7 days in the past.
|
||||
$post_atts = self::$post_atts;
|
||||
$post_atts['meta_input']['publish_to_discourse'] = 0;
|
||||
$post_atts['post_date'] = gmdate( 'Y-m-d H:i:s', strtotime( '-7 days' ) );
|
||||
$post_id = wp_insert_post( $post_atts, false, false );
|
||||
|
||||
// Trigger the publish_post_after_save method.
|
||||
$post = get_post( $post_id );
|
||||
$this->publish->publish_post_after_save( $post_id, $post );
|
||||
|
||||
// Ensure that publication has not occurred.
|
||||
$this->assertEmpty( get_post_meta( $post_id, 'discourse_post_id', true ) );
|
||||
|
||||
// Change force-publish-max-age to 20.
|
||||
self::$plugin_options['force-publish-max-age'] = 20;
|
||||
$this->publish->setup_options( self::$plugin_options );
|
||||
|
||||
// Trigger the publish_post_after_save method.
|
||||
$this->publish->publish_post_after_save( $post_id, $post );
|
||||
|
||||
// Ensure that publication has occurred.
|
||||
$this->assertEquals( get_post_meta( $post_id, 'discourse_post_id', true ), $discourse_post_id );
|
||||
$this->assertEquals( get_post_meta( $post_id, 'wpdc_publishing_response', true ), 'success' );
|
||||
|
||||
// Cleanup.
|
||||
wp_delete_post( $post_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Successful remote_post request returns original response.
|
||||
*/
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue