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

When published query is edited, offer save as draft #255

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 14 additions & 14 deletions composer.lock

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

76 changes: 74 additions & 2 deletions src/Admin/Editor.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use WPGraphQL\SmartCache\AdminErrors;
use WPGraphQL\SmartCache\Document;
use WPGraphQL\SmartCache\Document\Grant;
use WPGraphQL\SmartCache\Document\Group;
use WPGraphQL\SmartCache\Document\MaxAge;
use GraphQL\Error\SyntaxError;
use GraphQL\Server\RequestError;
Expand All @@ -34,6 +35,7 @@ public function admin_init() {
add_filter( sprintf( 'manage_edit-%s_sortable_columns', Document::TYPE_NAME ), [ $this, 'make_excerpt_column_sortable_in_admin_cb' ], 10, 1 );

add_filter( 'wp_editor_settings', [ $this, 'wp_editor_settings' ], 10, 2 );
add_action( 'post_submitbox_misc_actions', [ $this, 'draw_save_as_new_checkbox_cb' ] );
}

/**
Expand Down Expand Up @@ -71,7 +73,8 @@ public function validate_and_pre_save_cb( $data, $post ) {
return $data;
}

$document = new Document();
$document = new Document();
$existing_post = get_post( $post['ID'], ARRAY_A );

try {
// Check for empty post_content when publishing the query and throw
Expand All @@ -81,14 +84,43 @@ public function validate_and_pre_save_cb( $data, $post ) {

$data['post_content'] = $document->valid_or_throw( $post['post_content'], $post['ID'] );

// If post is already published and saving as published, and graphql query string is different on save
if ( 'publish' === $existing_post['post_status'] && 'publish' === $post['post_status'] ) {
// If selected to save as new
// phpcs:ignore
if ( isset( $_POST['graphql_query_save_new'] ) && 'save_as_new' === $_POST['graphql_query_save_new'] ) {
// phpcs:ignore
unset( $_POST['graphql_query_save_new'] );

// Reset some data in the post before save as new. $data doesn't have a post_id.
$data['post_status'] = 'draft';
$data['post_date_gmt'] = '0000-00-00 00:00:00';
$data['post_date'] = '';
if ( $data['post_title'] === $existing_post['post_title'] ) {
$data['post_title'] = $existing_post['post_title'] . ' (copy)';
}

$new_post_id = wp_insert_post( $data );

$group = new Group();
$group->save( $new_post_id, $group->get( $existing_post['ID'] ) );

// Redirect to the new post edit page after save
wp_safe_redirect( admin_url( sprintf( '/post.php?post=%d&action=edit', $new_post_id ) ) );
exit;
}

if ( $data['post_content'] !== $existing_post['post_content'] ) {
throw new RequestError( __( 'Changing query for published query is not allowed. Select the save as new and publish again.', 'wp-graphql-smart-cache' ) );
}
}
} catch ( RequestError $e ) {
AdminErrors::add_message( $e->getMessage() );

// If encountered invalid data when publishing query, revert some data. If draft, allow invalid query.
if ( 'publish' === $post['post_status'] ) {

// If has an existing published post and trying to publish with errors, bail before save_post
$existing_post = get_post( $post['ID'], ARRAY_A );
if ( $existing_post && 'publish' === $existing_post['post_status'] ) {

wp_safe_redirect( admin_url( sprintf( '/post.php?post=%d&action=edit', $post['ID'] ) ) );
Expand Down Expand Up @@ -363,4 +395,44 @@ public function wp_editor_settings( $settings, $editor_id ) {

return $settings;
}

/**
* @param \WP_Post $post
* @return void
*/
public function draw_save_as_new_checkbox_cb( $post ) {
$post_id = get_the_ID();

if ( Document::TYPE_NAME !== $post->post_type ) {
return;
}

if ( 'publish' !== $post->post_status ) {
return;
}

$html = '<div class="misc-pub-section misc-pub-section-last">';
$html .= '<input type="checkbox" id="graphql_query_save_new" name="graphql_query_save_new" value="save_as_new">';
$html .= '<label for="graphql_query_save_new">Save As Draft</label><br >';
$html .= '</div>';

/** @var array[] */
$allowed_html = [
'div' => [
'class' => true,
],
'input' => [
'type' => true,
'id' => true,
'name' => true,
'value' => true,
'checked' => true,
],
'br' => true,
];
echo wp_kses(
$html,
$allowed_html
);
}
}
12 changes: 12 additions & 0 deletions src/Document/Group.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,16 @@ public static function get( $post_id ) {
$item = get_the_terms( $post_id, self::TAXONOMY_NAME );
return ! is_wp_error( $item ) && isset( $item[0] ) && property_exists( $item[0], 'name' ) ? $item[0]->name : '';
}

/**
* Save the data
*
* @param int $post_id
* @param string $value
* @return array|false|\WP_Error Array of term taxonomy IDs of affected terms. WP_Error or false on failure.
*/
public function save( $post_id, $value ) {
return wp_set_post_terms( $post_id, $value, self::TAXONOMY_NAME );
}

}
88 changes: 88 additions & 0 deletions tests/functional/AdminEditorDocumentCest.php
Original file line number Diff line number Diff line change
Expand Up @@ -487,4 +487,92 @@ public function createNewQueryWithInvalidContentThenTrashItTest( FunctionalTeste
$I->dontSeeElement('//*[@id="plugin-message"]');
$I->dontSee('Invalid graphql query string "{ __typename broken"', '//*[@id="plugin-message"]');
}

public function havePublishedQueryWhenChangeQueryStringThePublishShowsErrorTest( FunctionalTester $I ) {
$post_title = 'test-post';
$original_query = '{ __typename }';
$normalized_query_string = "{\n __typename\n}\n";
$new_query = '{ __typename __typename }';
$the_new_normal = "{\n __typename\n __typename\n}\n";

// Create a new query in the admin editor
$I->loginAsAdmin();
$I->amOnPage( '/wp-admin/post-new.php?post_type=graphql_document');

// Add title should trigger auto-draft, but not save document
$I->fillField( "//input[@name='post_title']", $post_title);
$I->fillField( 'content', $original_query);
$I->fillField( 'graphql_query_maxage', '200');

// Publish post
$I->click('#publish');

$post_id_1 = $I->grabValueFrom(['name' => 'post_ID']);

$I->seePostInDatabase( [
'post_title' => $post_title,
'post_status' => 'publish',
'post_content' => $normalized_query_string,
]);

// new query
$I->fillField( 'content', $new_query );

// Shows save-as-new check box
$I->seeElement('//*[@id="graphql_query_save_new"]');
$I->see('Save As Draft');
$I->dontSeeCheckboxIsChecked("//input[@type='checkbox' and @name='graphql_query_save_new']");

// // Publish post button
$I->click('#publish');

$post_id_2 = $I->grabValueFrom(['name' => 'post_ID']);
$I->assertEquals( $post_id_1, $post_id_2 );
$I->seeInCurrentUrl( "/wp-admin/post.php?post=$post_id_1&action=edit" );

// Should not see success of the publish.
$I->dontSeeElement('//*[@id="message"]');
$I->dontSee('Post published.');
$I->dontSee('Post updated.');
$I->dontSee('Post saved.');
$I->dontSee('Publish immediately'); // has date because already published

// Shows error message
$I->seeElement('//*[@id="plugin-message"]');
$I->see('Changing query for published query is not allowed. Select the save as new and publish again.', '//*[@id="plugin-message"]');

// Shows save-as-new check box
$I->seeElement('//*[@id="graphql_query_save_new"]');
$I->see('Save As Draft');
$I->dontSeeCheckboxIsChecked("//input[@type='checkbox' and @name='graphql_query_save_new']");

// new query
$I->fillField( 'content', $new_query );

// Select the save as new
$I->checkOption("//input[@type='checkbox' and @name='graphql_query_save_new']");

// // Publish post button
$I->click('#publish');

$post_id_3 = $I->grabValueFrom(['name' => 'post_ID']);
$I->assertNotEquals( $post_id_1, $post_id_3 );
$I->seeInCurrentUrl( "/wp-admin/post.php?post=$post_id_3&action=edit" );

// should not see our admin error
$I->dontSeeElement('//*[@id="plugin-message"]');

// Saves the different query as draft with new title
$I->seePostInDatabase( [
'post_title' => "$post_title (copy)",
'post_status' => 'draft',
'post_content' => $the_new_normal,
]);

$post_id = $I->grabValueFrom(['name' => 'post_ID']);

// Should also save the other data for the new post
$I->seeInField(['name' => 'graphql_query_maxage'], '200');
}

}