Skip to content

Commit 2df911e

Browse files
jenkins-botGerrit Code Review
authored andcommitted
Merge "GQL: Introduce a type registry"
2 parents adc48de + d111191 commit 2df911e

File tree

5 files changed

+138
-116
lines changed

5 files changed

+138
-116
lines changed

repo/WikibaseRepo.datatypes.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,7 @@
352352
return WikibaseRepo::getStringValueNormalizer();
353353
},
354354
'graphql-value-type' => static function () {
355-
return WbReuse::getStringValueType();
355+
return WbReuse::getGraphQLTypes()->getStringValueType();
356356
},
357357
],
358358
'VT:time' => [
@@ -495,7 +495,7 @@
495495
return $value->getEntityId()->getSerialization();
496496
},
497497
'graphql-value-type' => static function() {
498-
return WbReuse::getEntityValueType();
498+
return WbReuse::getGraphQLTypes()->getEntityValueType();
499499
},
500500
],
501501
'PT:wikibase-item' => [
@@ -531,7 +531,7 @@
531531
},
532532
'graphql-value-type' => static function() {
533533
$itemLabelsResolver = WbReuse::getItemLabelsResolver();
534-
$labelProviderType = WbReuse::getLabelProviderType();
534+
$labelProviderType = WbReuse::getGraphQLTypes()->getLabelProviderType();
535535
$labelField = clone $labelProviderType->getField( 'label' ); // cloned to not override the resolver in other places
536536
$labelField->resolveFn = function( Statement|PropertyValuePair $valueProvider, array $args ) use( $itemLabelsResolver ) {
537537
/** @var EntityIdValue $idValue */
@@ -597,7 +597,7 @@
597597
},
598598
'graphql-value-type' => static function() {
599599
$labelsResolver = WbReuse::getPropertyLabelsResolver();
600-
$labelProviderType = WbReuse::getLabelProviderType();
600+
$labelProviderType = WbReuse::getGraphQLTypes()->getLabelProviderType();
601601
$labelField = clone $labelProviderType->getField( 'label' ); // cloned to not override the resolver in other places
602602
$labelField->resolveFn = function( Statement|PropertyValuePair $valueProvider, array $args ) use( $labelsResolver ) {
603603
/** @var EntityIdValue $idValue */

repo/domains/reuse/src/Infrastructure/GraphQL/Schema/Schema.php

Lines changed: 26 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
namespace Wikibase\Repo\Domains\Reuse\Infrastructure\GraphQL\Schema;
44

55
use GraphQL\Type\Definition\EnumType;
6-
use GraphQL\Type\Definition\InterfaceType;
76
use GraphQL\Type\Definition\ObjectType;
87
use GraphQL\Type\Definition\Type;
98
use GraphQL\Type\Schema as GraphQLSchema;
@@ -20,12 +19,7 @@
2019
class Schema extends GraphQLSchema {
2120
public function __construct(
2221
ItemResolver $itemResolver,
23-
private readonly ItemIdType $itemIdType,
24-
private readonly SiteIdType $siteIdType,
25-
private readonly LanguageCodeType $languageCodeType,
26-
private readonly PropertyValuePairType $propertyValuePairType,
27-
private readonly PropertyIdType $propertyIdType,
28-
private readonly InterfaceType $labelProviderType,
22+
private readonly Types $types,
2923
) {
3024
parent::__construct( [
3125
'query' => new ObjectType( [
@@ -34,7 +28,7 @@ public function __construct(
3428
'item' => [
3529
'type' => $this->itemType(),
3630
'args' => [
37-
'id' => Type::nonNull( $this->itemIdType ),
31+
'id' => Type::nonNull( $this->types->getItemIdType() ),
3832
],
3933
'resolve' => fn( $rootValue, array $args ) => $itemResolver->resolveItem( $args['id'] ),
4034
],
@@ -44,22 +38,23 @@ public function __construct(
4438
}
4539

4640
private function itemType(): ObjectType {
47-
$labelField = clone $this->labelProviderType->getField( 'label' ); // cloned to not override the resolver in other places
41+
$labelProviderType = $this->types->getLabelProviderType();
42+
$labelField = clone $labelProviderType->getField( 'label' ); // cloned to not override the resolver in other places
4843
$labelField->resolveFn = fn( Item $item, array $args ) => $item->labels
4944
->getLabelInLanguage( $args['languageCode'] )?->text;
5045

5146
return new ObjectType( [
5247
'name' => 'Item',
5348
'fields' => [
5449
'id' => [
55-
'type' => Type::nonNull( $this->itemIdType ),
50+
'type' => Type::nonNull( $this->types->getItemIdType() ),
5651
'resolve' => fn( Item $item ) => $item->id->getSerialization(),
5752
],
5853
$labelField,
5954
'description' => [
6055
'type' => Type::string(),
6156
'args' => [
62-
'languageCode' => Type::nonNull( $this->languageCodeType ),
57+
'languageCode' => Type::nonNull( $this->types->getLanguageCodeType() ),
6358
],
6459
'resolve' => fn( Item $item, array $args ) => $item->descriptions
6560
->getDescriptionInLanguage( $args['languageCode'] )?->text,
@@ -68,7 +63,7 @@ private function itemType(): ObjectType {
6863
// @phan-suppress-next-line PhanUndeclaredInvokeInCallable
6964
'type' => Type::nonNull( Type::listOf( Type::string() ) ),
7065
'args' => [
71-
'languageCode' => Type::nonNull( $this->languageCodeType ),
66+
'languageCode' => Type::nonNull( $this->types->getLanguageCodeType() ),
7267
],
7368
'resolve' => fn( Item $item, array $args ) => $item->aliases
7469
->getAliasesInLanguageInLanguage( $args['languageCode'] )?->aliases ?? [],
@@ -82,7 +77,7 @@ private function itemType(): ObjectType {
8277
],
8378
] ),
8479
'args' => [
85-
'siteId' => Type::nonNull( $this->siteIdType ),
80+
'siteId' => Type::nonNull( $this->types->getSiteIdType() ),
8681
],
8782
'resolve' => function( Item $item, array $args ) {
8883
$sitelink = $item->sitelinks->getSitelinkForSite( $args['siteId'] );
@@ -96,33 +91,35 @@ private function itemType(): ObjectType {
9691
// @phan-suppress-next-line PhanUndeclaredInvokeInCallable
9792
'type' => Type::nonNull( Type::listOf( $this->statementType() ) ),
9893
'args' => [
99-
'propertyId' => Type::nonNull( $this->propertyIdType ),
94+
'propertyId' => Type::nonNull( $this->types->getPropertyIdType() ),
10095
],
10196
'resolve' => fn( Item $item, array $args ) => $item->statements
10297
->getStatementsByPropertyId( new NumericPropertyId( $args[ 'propertyId' ] ) ),
10398
],
10499
],
105-
'interfaces' => [ $this->labelProviderType ],
100+
'interfaces' => [ $labelProviderType ],
106101
] );
107102
}
108103

109104
private function statementType(): ObjectType {
105+
$propertyValuePairType = $this->types->getPropertyValuePairType();
106+
110107
$qualifierType = new ObjectType( [
111108
'name' => 'Qualifier',
112109
'fields' => [
113-
$this->propertyValuePairType->getField( 'property' ),
114-
$this->propertyValuePairType->getField( 'value' ),
115-
$this->propertyValuePairType->getField( 'valueType' ),
110+
$propertyValuePairType->getField( 'property' ),
111+
$propertyValuePairType->getField( 'value' ),
112+
$propertyValuePairType->getField( 'valueType' ),
116113
],
117-
'interfaces' => [ $this->propertyValuePairType ],
114+
'interfaces' => [ $propertyValuePairType ],
118115
] );
119116

120117
return new ObjectType( [
121118
'name' => 'Statement',
122119
'fields' => [
123-
$this->propertyValuePairType->getField( 'property' ),
124-
$this->propertyValuePairType->getField( 'value' ),
125-
$this->propertyValuePairType->getField( 'valueType' ),
120+
$propertyValuePairType->getField( 'property' ),
121+
$propertyValuePairType->getField( 'value' ),
122+
$propertyValuePairType->getField( 'valueType' ),
126123
'id' => [
127124
'type' => Type::nonNull( Type::string() ),
128125
'resolve' => fn( Statement $statement ) => $statement->id,
@@ -135,7 +132,7 @@ private function statementType(): ObjectType {
135132
// @phan-suppress-next-line PhanUndeclaredInvokeInCallable
136133
'type' => Type::nonNull( Type::listOf( $qualifierType ) ),
137134
'args' => [
138-
'propertyId' => Type::nonNull( $this->propertyIdType ),
135+
'propertyId' => Type::nonNull( $this->types->getPropertyIdType() ),
139136
],
140137
'resolve' => fn( Statement $statement, $args ) => $statement->qualifiers
141138
->getQualifiersByPropertyId( new NumericPropertyId( $args[ 'propertyId' ] ) ),
@@ -146,7 +143,7 @@ private function statementType(): ObjectType {
146143
'resolve' => fn( Statement $statement ) => $statement->references,
147144
],
148145
],
149-
'interfaces' => [ $this->propertyValuePairType ],
146+
'interfaces' => [ $propertyValuePairType ],
150147
] );
151148
}
152149

@@ -168,14 +165,15 @@ private function rankType(): EnumType {
168165
}
169166

170167
private function referenceType(): ObjectType {
168+
$propertyValuePairType = $this->types->getPropertyValuePairType();
171169
$referencePartType = new ObjectType( [
172170
'name' => 'ReferencePart',
173171
'fields' => [
174-
$this->propertyValuePairType->getField( 'property' ),
175-
$this->propertyValuePairType->getField( 'value' ),
176-
$this->propertyValuePairType->getField( 'valueType' ),
172+
$propertyValuePairType->getField( 'property' ),
173+
$propertyValuePairType->getField( 'value' ),
174+
$propertyValuePairType->getField( 'valueType' ),
177175
],
178-
'interfaces' => [ $this->propertyValuePairType ],
176+
'interfaces' => [ $propertyValuePairType ],
179177
] );
180178

181179
return new ObjectType( [
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
<?php declare( strict_types=1 );
2+
3+
namespace Wikibase\Repo\Domains\Reuse\Infrastructure\GraphQL\Schema;
4+
5+
use GraphQL\Type\Definition\InterfaceType;
6+
use GraphQL\Type\Definition\ObjectType;
7+
use GraphQL\Type\Definition\ResolveInfo;
8+
use GraphQL\Type\Definition\Type;
9+
use Wikibase\Lib\DataTypeDefinitions;
10+
use Wikibase\Lib\SettingsArray;
11+
use Wikibase\Repo\Domains\Reuse\Domain\Model\PropertyValuePair;
12+
use Wikibase\Repo\Domains\Reuse\Domain\Model\Statement;
13+
use Wikibase\Repo\Domains\Reuse\Infrastructure\GraphQL\Resolvers\PropertyLabelsResolver;
14+
use Wikibase\Repo\SiteLinkGlobalIdentifiersProvider;
15+
16+
// The `return ... ??= ...;` shorthand syntax is too convenient in this file to disallow it.
17+
// phpcs:disable MediaWiki.Usage.AssignmentInReturn.AssignmentInReturn
18+
19+
/**
20+
* @license GPL-2.0-or-later
21+
*/
22+
class Types {
23+
private ?ItemIdType $itemIdType = null;
24+
private ?PropertyIdType $propertyIdType = null;
25+
private ?LanguageCodeType $languageCodeType = null;
26+
private ?SiteIdType $siteIdType = null;
27+
private ?PropertyValuePairType $propertyValuePairType = null;
28+
private ?InterfaceType $labelProviderType = null;
29+
private ?StringValueType $stringValueType = null;
30+
private ?ObjectType $entityValueType = null;
31+
32+
public function __construct(
33+
private readonly array $validLanguageCodes,
34+
private readonly SiteLinkGlobalIdentifiersProvider $siteLinkGlobalIdentifiersProvider,
35+
private readonly SettingsArray $repoSettings,
36+
private readonly PropertyLabelsResolver $propertyLabelsResolver,
37+
private readonly DataTypeDefinitions $dataTypeDefinitions,
38+
) {
39+
}
40+
41+
public function getItemIdType(): ItemIdType {
42+
return $this->itemIdType ??= new ItemIdType();
43+
}
44+
45+
public function getPropertyIdType(): PropertyIdType {
46+
return $this->propertyIdType ??= new PropertyIdType();
47+
}
48+
49+
public function getLanguageCodeType(): LanguageCodeType {
50+
return $this->languageCodeType ??= new LanguageCodeType( $this->validLanguageCodes );
51+
}
52+
53+
public function getSiteIdType(): SiteIdType {
54+
return $this->siteIdType ??= new SiteIdType( $this->siteLinkGlobalIdentifiersProvider, $this->repoSettings );
55+
}
56+
57+
public function getPropertyValuePairType(): PropertyValuePairType {
58+
return $this->propertyValuePairType ??= new PropertyValuePairType(
59+
new PredicatePropertyType( $this->propertyLabelsResolver, $this->getLabelProviderType() ),
60+
new ValueType( $this->dataTypeDefinitions->getGraphqlValueTypes() ),
61+
new ValueTypeType(),
62+
);
63+
}
64+
65+
public function getLabelProviderType(): InterfaceType {
66+
return $this->labelProviderType ??= new InterfaceType( [
67+
'name' => 'LabelProvider',
68+
'fields' => [
69+
'label' => [
70+
'type' => Type::string(),
71+
'args' => [
72+
'languageCode' => Type::nonNull( $this->getLanguageCodeType() ),
73+
],
74+
],
75+
],
76+
] );
77+
}
78+
79+
public function getStringValueType(): StringValueType {
80+
return $this->stringValueType ??= new StringValueType();
81+
}
82+
83+
public function getEntityValueType(): ObjectType {
84+
return $this->entityValueType ??= new ObjectType( [
85+
'name' => 'EntityValue',
86+
'fields' => [ 'id' => Type::nonNull( Type::string() ) ],
87+
'resolveField' => fn( Statement|PropertyValuePair $valueProvider, $args, $context, ResolveInfo $info ) => $valueProvider->value
88+
->getArrayValue()[ $info->fieldName ] ?? null,
89+
] );
90+
}
91+
}

0 commit comments

Comments
 (0)