map() public static method

public static map ( array | Traversable $traversable, callable $fn ) : array
$traversable array | Traversable
$fn callable function($value, $key) => $newValue
return array
 private function withModifiers($types)
 {
     return array_merge(Utils::map($types, function ($type) {
         return Type::listOf($type);
     }), Utils::map($types, function ($type) {
         return Type::nonNull($type);
     }), Utils::map($types, function ($type) {
         return Type::nonNull(Type::listOf($type));
     }));
 }
示例#2
0
 /**
  * Return implementations of `type` that include `fieldName` as a valid field.
  *
  * @param Schema $schema
  * @param AbstractType $type
  * @param $fieldName
  * @return array
  */
 static function getImplementationsIncludingField(Schema $schema, AbstractType $type, $fieldName)
 {
     $types = $schema->getPossibleTypes($type);
     $types = Utils::filter($types, function ($t) use($fieldName) {
         return isset($t->getFields()[$fieldName]);
     });
     $types = Utils::map($types, function ($t) {
         return $t->name;
     });
     sort($types);
     return $types;
 }
示例#3
0
 private function detectCycleRecursive(FragmentDefinition $fragment, ValidationContext $context)
 {
     $fragmentName = $fragment->name->value;
     $this->visitedFrags[$fragmentName] = true;
     $spreadNodes = $context->getFragmentSpreads($fragment);
     if (empty($spreadNodes)) {
         return;
     }
     $this->spreadPathIndexByName[$fragmentName] = count($this->spreadPath);
     for ($i = 0; $i < count($spreadNodes); $i++) {
         $spreadNode = $spreadNodes[$i];
         $spreadName = $spreadNode->name->value;
         $cycleIndex = isset($this->spreadPathIndexByName[$spreadName]) ? $this->spreadPathIndexByName[$spreadName] : null;
         if ($cycleIndex === null) {
             $this->spreadPath[] = $spreadNode;
             if (empty($this->visitedFrags[$spreadName])) {
                 $spreadFragment = $context->getFragment($spreadName);
                 if ($spreadFragment) {
                     $this->detectCycleRecursive($spreadFragment, $context);
                 }
             }
             array_pop($this->spreadPath);
         } else {
             $cyclePath = array_slice($this->spreadPath, $cycleIndex);
             $nodes = $cyclePath;
             if (is_array($spreadNode)) {
                 $nodes = array_merge($nodes, $spreadNode);
             } else {
                 $nodes[] = $spreadNode;
             }
             $context->reportError(new Error(self::cycleErrorMessage($spreadName, Utils::map($cyclePath, function ($s) {
                 return $s->name->value;
             })), $nodes));
         }
     }
     $this->spreadPathIndexByName[$fragmentName] = null;
 }
 private function subfieldConflicts(array $conflicts, $responseName, FieldNode $ast1, FieldNode $ast2)
 {
     if (!empty($conflicts)) {
         return [[$responseName, Utils::map($conflicts, function ($conflict) {
             return $conflict[0];
         })], array_reduce($conflicts, function ($allFields, $conflict) {
             return array_merge($allFields, $conflict[1]);
         }, [$ast1]), array_reduce($conflicts, function ($allFields, $conflict) {
             return array_merge($allFields, $conflict[2]);
         }, [$ast2])];
     }
 }
示例#5
0
 /**
  * Utility for validators which determines if a value literal AST is valid given
  * an input type.
  *
  * Note that this only validates literal values, variables are assumed to
  * provide values of the correct type.
  *
  * @return array
  */
 public static function isValidLiteralValue(Type $type, $valueNode)
 {
     // A value must be provided if the type is non-null.
     if ($type instanceof NonNull) {
         if (!$valueNode || $valueNode instanceof NullValueNode) {
             return ['Expected "' . Utils::printSafe($type) . '", found null.'];
         }
         return static::isValidLiteralValue($type->getWrappedType(), $valueNode);
     }
     if (!$valueNode || $valueNode instanceof NullValueNode) {
         return [];
     }
     // This function only tests literals, and assumes variables will provide
     // values of the correct type.
     if ($valueNode instanceof VariableNode) {
         return [];
     }
     // Lists accept a non-list value as a list of one.
     if ($type instanceof ListOfType) {
         $itemType = $type->getWrappedType();
         if ($valueNode instanceof ListValueNode) {
             $errors = [];
             foreach ($valueNode->values as $index => $itemNode) {
                 $tmp = static::isValidLiteralValue($itemType, $itemNode);
                 if ($tmp) {
                     $errors = array_merge($errors, Utils::map($tmp, function ($error) use($index) {
                         return "In element #{$index}: {$error}";
                     }));
                 }
             }
             return $errors;
         } else {
             return static::isValidLiteralValue($itemType, $valueNode);
         }
     }
     // Input objects check each defined field and look for undefined fields.
     if ($type instanceof InputObjectType) {
         if ($valueNode->kind !== NodeKind::OBJECT) {
             return ["Expected \"{$type->name}\", found not an object."];
         }
         $fields = $type->getFields();
         $errors = [];
         // Ensure every provided field is defined.
         $fieldNodes = $valueNode->fields;
         foreach ($fieldNodes as $providedFieldNode) {
             if (empty($fields[$providedFieldNode->name->value])) {
                 $errors[] = "In field \"{$providedFieldNode->name->value}\": Unknown field.";
             }
         }
         // Ensure every defined field is valid.
         $fieldNodeMap = Utils::keyMap($fieldNodes, function ($fieldNode) {
             return $fieldNode->name->value;
         });
         foreach ($fields as $fieldName => $field) {
             $result = static::isValidLiteralValue($field->getType(), isset($fieldNodeMap[$fieldName]) ? $fieldNodeMap[$fieldName]->value : null);
             if ($result) {
                 $errors = array_merge($errors, Utils::map($result, function ($error) use($fieldName) {
                     return "In field \"{$fieldName}\": {$error}";
                 }));
             }
         }
         return $errors;
     }
     if ($type instanceof LeafType) {
         // Scalar/Enum input checks to ensure the type can parse the value to
         // a non-null value.
         $parseResult = $type->parseLiteral($valueNode);
         if (null === $parseResult) {
             $printed = Printer::doPrint($valueNode);
             return ["Expected type \"{$type->name}\", found {$printed}."];
         }
         return [];
     }
     throw new InvariantViolation('Must be input type');
 }
示例#6
0
 /**
  * @it produces double linked list of tokens, including comments
  */
 public function testDoubleLinkedList()
 {
     $lexer = new Lexer(new Source('{
   #comment
   field
 }'));
     $startToken = $lexer->token;
     do {
         $endToken = $lexer->advance();
         // Lexer advances over ignored comment tokens to make writing parsers
         // easier, but will include them in the linked list result.
         $this->assertNotEquals('Comment', $endToken->kind);
     } while ($endToken->kind !== '<EOF>');
     $this->assertEquals(null, $startToken->prev);
     $this->assertEquals(null, $endToken->next);
     $tokens = [];
     for ($tok = $startToken; $tok; $tok = $tok->next) {
         if (!empty($tokens)) {
             // Tokens are double-linked, prev should point to last seen token.
             $this->assertSame($tokens[count($tokens) - 1], $tok->prev);
         }
         $tokens[] = $tok;
     }
     $this->assertEquals(['<SOF>', '{', 'Comment', 'Name', '}', '<EOF>'], Utils::map($tokens, function ($tok) {
         return $tok->kind;
     }));
 }
示例#7
0
文件: Error.php 项目: aeshion/ZeroPHP
 /**
  * Returns array representation of error suitable for serialization
  *
  * @return array
  */
 public function toSerializableArray()
 {
     $arr = ['message' => $this->getMessage()];
     $locations = Utils::map($this->getLocations(), function (SourceLocation $loc) {
         return $loc->toSerializableArray();
     });
     if (!empty($locations)) {
         $arr['locations'] = $locations;
     }
     if (!empty($this->path)) {
         $arr['path'] = $this->path;
     }
     return $arr;
 }
 public function testRespectsListsOfAbstractTypeWhenResolvingViaMap()
 {
     $type1 = null;
     $type2 = null;
     $type3 = null;
     $resolveType = function ($value) use(&$type1, &$type2, &$type3) {
         switch ($value['type']) {
             case 'Type1':
                 return $type1;
             case 'Type2':
                 return $type2;
             case 'Type3':
             default:
                 return $type3;
         }
     };
     $mapValues = function ($typeValues, $args) {
         return Utils::map($typeValues, function ($value) use($args) {
             if (array_key_exists('foo', $value)) {
                 return json_encode(['value' => $value, 'args' => $args]);
             } else {
                 return null;
             }
         });
     };
     $interface = new InterfaceType(['name' => 'SomeInterface', 'fields' => ['foo' => ['type' => Type::string()]], 'resolveType' => $resolveType]);
     $type1 = new ObjectType(['name' => 'Type1', 'fields' => ['foo' => ['type' => Type::string(), 'map' => $mapValues]], 'interfaces' => [$interface]]);
     $type2 = new ObjectType(['name' => 'Type2', 'fields' => ['foo' => ['type' => Type::string(), 'map' => $mapValues]], 'interfaces' => [$interface]]);
     $type3 = new ObjectType(['name' => 'Type3', 'fields' => ['bar' => ['type' => Type::listOf(Type::string()), 'map' => function ($type3Values, $args) {
         return Utils::map($type3Values, function ($value) use($args) {
             return [json_encode(['value' => $value, 'args' => $args])];
         });
     }]]]);
     $union = new UnionType(['name' => 'SomeUnion', 'types' => [$type1, $type3], 'resolveType' => $resolveType]);
     $complexType = new ObjectType(['name' => 'ComplexType', 'fields' => ['iface' => ['type' => $interface], 'ifaceList' => ['type' => Type::listOf($interface)], 'union' => ['type' => $union], 'unionList' => ['type' => Type::listOf($union)]]]);
     $type1values = [['type' => 'Type1', 'foo' => 'str1'], ['type' => 'Type1'], ['type' => 'Type1', 'foo' => null]];
     $type2values = [['type' => 'Type2', 'foo' => 'str1'], ['type' => 'Type2', 'foo' => null], ['type' => 'Type2']];
     $type3values = [['type' => 'Type3', 'bar' => ['str1', 'str2']], ['type' => 'Type3', 'bar' => null]];
     $complexTypeValues = ['iface' => $type1values[0], 'ifaceList' => array_merge($type1values, $type2values), 'union' => $type3values[0], 'unionList' => array_merge($type1values, $type3values)];
     $expected = ['data' => ['test' => ['iface' => ['foo' => json_encode(['value' => $type1values[0], 'args' => []])], 'ifaceList' => [['foo' => '{"value":{"type":"Type1","foo":"str1"},"args":[]}'], ['foo' => null], ['foo' => '{"value":{"type":"Type1","foo":null},"args":[]}'], ['foo' => '{"value":{"type":"Type2","foo":"str1"},"args":[]}'], ['foo' => '{"value":{"type":"Type2","foo":null},"args":[]}'], ['foo' => null]], 'union' => ['bar' => ['{"value":{"type":"Type3","bar":["str1","str2"]},"args":[]}']], 'unionList' => [['foo' => '{"value":{"type":"Type1","foo":"str1"},"args":[]}'], ['foo' => null], ['foo' => '{"value":{"type":"Type1","foo":null},"args":[]}'], ['bar' => ['{"value":{"type":"Type3","bar":["str1","str2"]},"args":[]}']], ['bar' => ['{"value":{"type":"Type3","bar":null},"args":[]}']]]]]];
     $schema = new Schema(new ObjectType(['name' => 'Query', 'fields' => ['test' => ['type' => $complexType, 'resolve' => function () use($complexTypeValues) {
         return $complexTypeValues;
     }]]]));
     $query = '{
         test {
             iface{foo},
             ifaceList{foo}
             union {
                 ... on Type1 {
                     foo
                 }
                 ... on Type3 {
                     bar
                 }
             }
             unionList {
                 ... on Type1 {
                     foo
                 }
                 ... on Type3 {
                     bar
                 }
             }
         }
     }';
     $query = Parser::parse($query);
     $result = Executor::execute($schema, $query);
     $this->assertEquals($expected, $result->toArray());
 }
示例#9
0
 /**
  * Given a PHP value and a GraphQL type, determine if the value will be
  * accepted for that type. This is primarily useful for validating the
  * runtime values of query variables.
  *
  * @param $value
  * @param InputType $type
  * @return array
  */
 private static function isValidPHPValue($value, InputType $type)
 {
     // A value must be provided if the type is non-null.
     if ($type instanceof NonNull) {
         if (null === $value) {
             return ['Expected "' . Utils::printSafe($type) . '", found null.'];
         }
         return self::isValidPHPValue($value, $type->getWrappedType());
     }
     if (null === $value) {
         return [];
     }
     // Lists accept a non-list value as a list of one.
     if ($type instanceof ListOfType) {
         $itemType = $type->getWrappedType();
         if (is_array($value)) {
             $tmp = [];
             foreach ($value as $index => $item) {
                 $errors = self::isValidPHPValue($item, $itemType);
                 $tmp = array_merge($tmp, Utils::map($errors, function ($error) use($index) {
                     return "In element #{$index}: {$error}";
                 }));
             }
             return $tmp;
         }
         return self::isValidPHPValue($value, $itemType);
     }
     // Input objects check each defined field.
     if ($type instanceof InputObjectType) {
         if (!is_object($value) && !is_array($value)) {
             return ["Expected \"{$type->name}\", found not an object."];
         }
         $fields = $type->getFields();
         $errors = [];
         // Ensure every provided field is defined.
         $props = is_object($value) ? get_object_vars($value) : $value;
         foreach ($props as $providedField => $tmp) {
             if (!isset($fields[$providedField])) {
                 $errors[] = "In field \"{$providedField}\": Unknown field.";
             }
         }
         // Ensure every defined field is valid.
         foreach ($fields as $fieldName => $tmp) {
             $newErrors = self::isValidPHPValue(isset($value[$fieldName]) ? $value[$fieldName] : null, $fields[$fieldName]->getType());
             $errors = array_merge($errors, Utils::map($newErrors, function ($error) use($fieldName) {
                 return "In field \"{$fieldName}\": {$error}";
             }));
         }
         return $errors;
     }
     if ($type instanceof LeafType) {
         // Scalar/Enum input checks to ensure the type can parse the value to
         // a non-null value.
         $parseResult = $type->parseValue($value);
         if (null === $parseResult) {
             $v = json_encode($value);
             return ["Expected type \"{$type->name}\", found {$v}."];
         }
         return [];
     }
     throw new InvariantViolation('Must be input type');
 }
示例#10
0
 /**
  * Given a type and any value, return a runtime value coerced to match the type.
  */
 private static function coerceValue(Type $type, $value)
 {
     if ($type instanceof NonNull) {
         // Note: we're not checking that the result of coerceValue is non-null.
         // We only call this function after calling isValidPHPValue.
         return self::coerceValue($type->getWrappedType(), $value);
     }
     if (null === $value) {
         return null;
     }
     if ($type instanceof ListOfType) {
         $itemType = $type->getWrappedType();
         if (is_array($value) || $value instanceof \Traversable) {
             return Utils::map($value, function ($item) use($itemType) {
                 return Values::coerceValue($itemType, $item);
             });
         } else {
             return [self::coerceValue($itemType, $value)];
         }
     }
     if ($type instanceof InputObjectType) {
         $fields = $type->getFields();
         $obj = [];
         foreach ($fields as $fieldName => $field) {
             $fieldValue = self::coerceValue($field->getType(), isset($value[$fieldName]) ? $value[$fieldName] : null);
             if (null === $fieldValue) {
                 $fieldValue = $field->defaultValue;
             }
             if (null !== $fieldValue) {
                 $obj[$fieldName] = $fieldValue;
             }
         }
         return $obj;
     }
     if ($type instanceof LeafType) {
         return $type->parseValue($value);
     }
     throw new InvariantViolation('Must be input type');
 }
示例#11
0
 /**
  * @return InterfaceType[]
  */
 public function getInterfaces()
 {
     if (null === $this->interfaces) {
         $interfaces = isset($this->config['interfaces']) ? $this->config['interfaces'] : [];
         $interfaces = is_callable($interfaces) ? call_user_func($interfaces) : $interfaces;
         // TODO: Return some sort of generator to avoid multiple loops
         $interfaces = Utils::map($interfaces, function ($iface) {
             return $iface instanceof DefinitionContainer ? $iface->getDefinition() : $iface;
         });
         $this->interfaces = $interfaces;
     }
     return $this->interfaces;
 }