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

make it easier to extend select fields #799

Merged
merged 2 commits into from
Sep 25, 2021
Merged
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
2 changes: 1 addition & 1 deletion phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ parameters:
path: src/Support/AliasArguments/ArrayKeyChange.php

-
message: "#^Parameter \\#2 \\$schema of method Rebing\\\\GraphQL\\\\Support\\\\ExecutionMiddleware\\\\AbstractExecutionMiddleware\\:\\:handle\\(\\) expects GraphQL\\\\Type\\\\Schema, Closure\\(\\.\\.\\.mixed\\)\\: mixed given\\.$#"
message: "#^Parameter \\#2 \\$schema of method Rebing\\\\GraphQL\\\\Support\\\\ExecutionMiddleware\\\\AbstractExecutionMiddleware\\:\\:handle\\(\\) expects GraphQL\\\\Type\\\\Schema, Closure given\\.$#"
count: 1
path: src/Support/ExecutionMiddleware/AbstractExecutionMiddleware.php

Expand Down
23 changes: 15 additions & 8 deletions src/Support/Field.php
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ protected function getResolver(): ?Closure

if (method_exists($instance, 'terminate')) {
app()->terminating(function () use ($arguments, $instance, $result): void {
$instance->terminate($this, ...\array_slice($arguments, 1), ...[$result]);
$instance->terminate($this, ...array_slice($arguments, 1), ...[$result]);
});
}
}
Expand Down Expand Up @@ -198,13 +198,13 @@ protected function originalResolver(): ?Closure
$arguments[1] = $this->getArgs($arguments);

// Authorize
if (true != \call_user_func_array($authorize, $arguments)) {
if (true != call_user_func_array($authorize, $arguments)) {
throw new AuthorizationError($this->getAuthorizationMessage());
}

$method = new ReflectionMethod($this, 'resolve');

$additionalParams = \array_slice($method->getParameters(), 3);
$additionalParams = array_slice($method->getParameters(), 3);

$additionalArguments = array_map(function ($param) use ($arguments, $fieldsAndArguments) {
$paramType = $param->getType();
Expand All @@ -216,12 +216,12 @@ protected function originalResolver(): ?Closure
$className = $param->getType()->getName();

if (Closure::class === $className) {
return function () use ($arguments, $fieldsAndArguments): SelectFields {
return function () use ($arguments, $fieldsAndArguments) {
return $this->instanciateSelectFields($arguments, $fieldsAndArguments);
};
}

if (SelectFields::class === $className) {
if ($this->selectFieldClass() === $className) {
return $this->instanciateSelectFields($arguments, $fieldsAndArguments);
}

Expand All @@ -232,7 +232,7 @@ protected function originalResolver(): ?Closure
return app()->make($className);
}, $additionalParams);

return \call_user_func_array($resolver, array_merge(
return call_user_func_array($resolver, array_merge(
[$arguments[0], $arguments[1], $arguments[2]],
$additionalArguments
));
Expand All @@ -243,11 +243,18 @@ protected function originalResolver(): ?Closure
* @param array<int,mixed> $arguments
* @param array<string,mixed> $fieldsAndArguments
*/
private function instanciateSelectFields(array $arguments, array $fieldsAndArguments): SelectFields
protected function instanciateSelectFields(array $arguments, array $fieldsAndArguments): SelectFields
{
$ctx = $arguments[2] ?? null;

return new SelectFields($this->type(), $arguments[1], $ctx, $fieldsAndArguments);
$selectFieldsClass = $this->selectFieldClass();

return new $selectFieldsClass($this->type(), $arguments[1], $ctx, $fieldsAndArguments);
}

protected function selectFieldClass(): string
{
return SelectFields::class;
Copy link
Collaborator

Choose a reason for hiding this comment

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

boom

This means we're agreeing and opening the SelectFields class to the world and encourage extending from it.

I think given the state of complexity and (missing) test coverage of that class, It's not unreasonable to say this is probably my worst nightmare 😄


I'm in favour of the PR, but let me sort out the other issues first please; will get back to you.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

😅

Copy link
Contributor Author

@crissi crissi Jun 24, 2021

Choose a reason for hiding this comment

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

Np, my plan in the long run is to hack less in this file and instead make prs that might benefit others. But right now this would help me to more easily see the actually changes I have made from the code I just copied over because of dependencies.

}

protected function aliasArgs(array $arguments): array
Expand Down
32 changes: 16 additions & 16 deletions src/Support/SelectFields.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public function __construct(GraphqlType $parentType, array $queryArgs, $ctx, arr
];

/** @var array{0:mixed[],1:mixed[]} $result */
$result = self::getSelectableFieldsAndRelations($queryArgs, $requestedFields, $parentType, null, true, $ctx);
$result = static::getSelectableFieldsAndRelations($queryArgs, $requestedFields, $parentType, null, true, $ctx);

[$this->select, $this->relations] = $result;
}
Expand Down Expand Up @@ -88,7 +88,7 @@ public static function getSelectableFieldsAndRelations(
if (null !== $primaryKey) {
$primaryKey = $parentTable ? ($parentTable . '.' . $primaryKey) : $primaryKey;

if (!\in_array($primaryKey, $select)) {
if (!in_array($primaryKey, $select)) {
$select[] = $primaryKey;
}
}
Expand Down Expand Up @@ -193,12 +193,12 @@ protected static function handleFields(
}
// With

elseif (\is_array($field['fields']) && !empty($field['fields']) && $queryable) {
elseif (is_array($field['fields']) && !empty($field['fields']) && $queryable) {
if (isset($parentType->config['model'])) {
// Get the next parent type, so that 'with' queries could be made
// Both keys for the relation are required (e.g 'id' <-> 'user_id')
$relationsKey = $fieldObject->config['alias'] ?? $key;
$relation = \call_user_func([app($parentType->config['model']), $relationsKey]);
$relation = call_user_func([app($parentType->config['model']), $relationsKey]);

static::handleRelation($select, $relation, $parentTable, $field);

Expand Down Expand Up @@ -279,15 +279,15 @@ protected static function addFieldToSelect($field, array &$select, ?string $pare
return;
}

if ($forRelation && !\array_key_exists($field, $select['fields'])) {
if ($forRelation && !array_key_exists($field, $select['fields'])) {
$select['fields'][$field] = [
'args' => [],
'fields' => true,
];
} elseif (!$forRelation && !\in_array($field, $select)) {
} elseif (!$forRelation && !in_array($field, $select)) {
$field = $parentTable ? ($parentTable . '.' . $field) : $field;

if (!\in_array($field, $select)) {
if (!in_array($field, $select)) {
$select[] = $field;
}
}
Expand Down Expand Up @@ -318,14 +318,14 @@ protected static function validateField(FieldDefinition $fieldObject, array $que

switch ($privacyClass) {
// If privacy given as a closure
case \is_callable($privacyClass):
case is_callable($privacyClass):
if (false === $privacyClass($queryArgs, $ctx)) {
$selectable = null;
}

break;
// If Privacy class given
case \is_string($privacyClass):
case is_string($privacyClass):
/** @var Privacy $instance */
$instance = app($privacyClass);

Expand Down Expand Up @@ -381,27 +381,27 @@ protected static function handleRelation(array &$select, $relation, ?string $par
$foreignKeyType = $relation->getMorphType();
$foreignKeyType = $parentTable ? ($parentTable . '.' . $foreignKeyType) : $foreignKeyType;

if (!\in_array($foreignKey, $select)) {
if (!in_array($foreignKey, $select)) {
$select[] = $foreignKey;
}

if (!\in_array($foreignKeyType, $select)) {
if (!in_array($foreignKeyType, $select)) {
$select[] = $foreignKeyType;
}
} elseif (is_a($relation, BelongsTo::class)) {
if (!\in_array($foreignKey, $select)) {
if (!in_array($foreignKey, $select)) {
$select[] = $foreignKey;
}
} // If 'HasMany', then add it in the 'with'
elseif ((is_a($relation, HasMany::class) || is_a($relation, MorphMany::class) || is_a(
$relation,
HasOne::class
) || is_a($relation, MorphOne::class)) &&
!\array_key_exists($foreignKey, $field)) {
!array_key_exists($foreignKey, $field)) {
$segments = explode('.', $foreignKey);
$foreignKey = end($segments);

if (!\array_key_exists($foreignKey, $field)) {
if (!array_key_exists($foreignKey, $field)) {
$field['fields'][$foreignKey] = static::ALWAYS_RELATION_KEY;
}

Expand All @@ -425,7 +425,7 @@ protected static function addAlwaysFields(
if (isset($fieldObject->config['always'])) {
$always = $fieldObject->config['always'];

if (\is_string($always)) {
if (is_string($always)) {
$always = explode(',', $always);
}

Expand Down Expand Up @@ -491,7 +491,7 @@ function (GraphqlType $type) use ($query) {
);
$typesFiltered = array_values($typesFiltered ?? []);

if (1 === \count($typesFiltered)) {
if (1 === count($typesFiltered)) {
/* @var GraphqlType $type */
$type = $typesFiltered[0];
$relationField = $type->getField($key);
Expand Down