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

feature: Add variable validation rule to query save #249

Closed
57 changes: 28 additions & 29 deletions composer.lock

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

4 changes: 2 additions & 2 deletions src/Admin/Editor.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,12 @@ public function admin_init() {
public function untrashed_post_cb( $post_id, $previous_status ) {
// If have errors when validating the post content/data, do not show those in the admin when untrash.
$untrashed_post = get_post( $post_id );

// Bail if the untrashed post is not a GraphQL Document
if ( ! isset( $untrashed_post->post_type ) || Document::TYPE_NAME !== $untrashed_post->post_type ) {
return;
}

delete_transient( AdminErrors::TRANSIENT_NAME );
}

Expand Down
10 changes: 10 additions & 0 deletions src/Document.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use WPGraphQL\SmartCache\Admin\Settings;
use GraphQL\Error\SyntaxError;
use GraphQL\Server\RequestError;
use GraphQL\Validator\DocumentValidator;

class Document {

Expand Down Expand Up @@ -306,6 +307,15 @@ public function valid_or_throw( $post_content, $post_id ) {
throw new RequestError( sprintf( __( 'This query has already been associated with another query "%s"', 'wp-graphql-smart-cache' ), $existing_post->post_title ) );
}

// During save/parse of query string, check for variables of the query string.
// "To save this query, arguments should use variables instead of static values."
$rules = DocumentValidator::defaultRules();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This adds the other rules to the query string validation.

$rules['argument_should_be_variable'] = new \WPGraphQL\SmartCache\ValidationRules\ArgShouldBeVariable();
$validationErrors = DocumentValidator::validate( \WPGraphQL::get_schema(), $ast, $rules );
if ( count( $validationErrors ) > 0 ) {
throw new RequestError( __( 'Validation Error: ', 'wp-graphql-smart-cache' ) . $validationErrors[0]->getMessage() );
}

// Format the query string and save that
return \GraphQL\Language\Printer::doPrint( $ast );
} catch ( SyntaxError $e ) {
Expand Down
52 changes: 52 additions & 0 deletions src/ValidationRules/ArgShouldBeVariable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

namespace WPGraphQL\SmartCache\ValidationRules;

use GraphQL\Error\Error;
use GraphQL\Language\AST\NodeKind;
use GraphQL\Language\AST\ArgumentNode;
use GraphQL\Validator\Rules\ValidationRule;
use GraphQL\Validator\ValidationContext;

/**
* Class ArgShouldBeVariable
*
* @package WPGraphQL\SmartCache\Rules
*/
class ArgShouldBeVariable extends ValidationRule {

/**
* Returns structure suitable for GraphQL\Language\Visitor
*
* @see \GraphQL\Language\Visitor
*
* @return mixed[]
*/
public function getVisitor( ValidationContext $context ) {

return [
NodeKind::ARGUMENT => [
'enter' => function ( ArgumentNode $node ) use ( $context ) {
// Arguments in operation are process here, ex. post( id: "1", idType: DATABASE_ID )

// If this argument should map to a variable
// For a string or "idType" enum
if ( in_array( $node->value->kind, [ 'StringValue', 'EnumValue' ], true ) ) {
$context->reportError(new Error(
self::shouldBeVariableMessage( $node->name->value ),
$node
));
}
},
],
];
}

/**
* @param string $varName
* @return string
*/
public static function shouldBeVariableMessage( $varName ) {
return sprintf( __( 'Argument "$%s" should be a variable.', 'wp-graphql-smart-cache' ), $varName );
}
}
Loading
Loading