VariablesDefaultValueAllowed.php 2.01 KB
Newer Older
Ketan's avatar
Ketan committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
<?php
namespace GraphQL\Validator\Rules;

use GraphQL\Error\Error;
use GraphQL\Language\AST\FragmentDefinitionNode;
use GraphQL\Language\AST\NodeKind;
use GraphQL\Language\AST\SelectionSetNode;
use GraphQL\Language\AST\VariableDefinitionNode;
use GraphQL\Language\Visitor;
use GraphQL\Type\Definition\NonNull;
use GraphQL\Validator\ValidationContext;

/**
 * Variable's default value is allowed
 *
 * A GraphQL document is only valid if all variable default values are allowed
 * due to a variable not being required.
 */
class VariablesDefaultValueAllowed extends AbstractValidationRule
{
    static function defaultForRequiredVarMessage($varName, $type, $guessType)
    {
        return (
            "Variable \"\${$varName}\" of type \"{$type}\" is required and " .
            'will not use the default value. ' .
            "Perhaps you meant to use type \"{$guessType}\"."
        );
    }

    public function getVisitor(ValidationContext $context)
    {
        return [
            NodeKind::VARIABLE_DEFINITION => function(VariableDefinitionNode $node) use ($context) {
                $name = $node->variable->name->value;
                $defaultValue = $node->defaultValue;
                $type = $context->getInputType();
                if ($type instanceof NonNull && $defaultValue) {
                    $context->reportError(
                      new Error(
                          self::defaultForRequiredVarMessage(
                              $name,
                              $type,
                              $type->getWrappedType()
                          ),
                          [$defaultValue]
                      )
                    );
                }

                return Visitor::skipNode();
            },
            NodeKind::SELECTION_SET => function(SelectionSetNode $node) {
                return Visitor::skipNode();
            },
            NodeKind::FRAGMENT_DEFINITION => function(FragmentDefinitionNode $node) {
                return Visitor::skipNode();
            },
        ];
    }
}