Skip to content

Commit

Permalink
It’s now possible to use aliases when eager-loading elements via Grap…
Browse files Browse the repository at this point in the history
…hQL.

Resolves #5481
  • Loading branch information
andris-sevcenko committed Jun 18, 2020
1 parent 61354b7 commit 04af22c
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 15 deletions.
1 change: 1 addition & 0 deletions CHANGELOG-v3.5.md
Expand Up @@ -256,6 +256,7 @@
- Extra entry revisions (per the `maxRevisions` config setting) are now pruned via a background job. ([#5902](https://github.com/craftcms/cms/issues/5902))
- Database backups created by the Database Backup utility are now saved as zip files. ([#5822](https://github.com/craftcms/cms/issues/5822))
- It’s now possible to specify aliases when eager-loading elements via the `with` param. ([#5793](https://github.com/craftcms/cms/issues/5793))
- It’s now possible to use aliases when eager-loading elements via GraphQL. ([#5481](https://github.com/craftcms/cms/issues/5481))
- It’s now possible to eager-load elements’ ancestors and parents. ([#1382](https://github.com/craftcms/cms/issues/1382))
- The `cpTrigger` config setting can now be set to `null`. ([#5122](https://github.com/craftcms/cms/issues/5122))
- The `pathParam` config setting can now be set to `null`. ([#5676](https://github.com/craftcms/cms/issues/5676))
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG-v3.md
Expand Up @@ -20,6 +20,7 @@
- Entry draft forms no longer have a primary action, and the <kbd>Ctrl</kbd>/<kbd>Command</kbd> + <kbd>S</kbd> keyboard shortcut now forces a resave of the draft, rather than publishing it. ([#6199](https://github.com/craftcms/cms/issues/6199))
- All built-in success/fail flash messages are now customizable by passing a hashed `successMessage`/`failMessage` param with the request. ([#6192](https://github.com/craftcms/cms/issues/6192))
- Craft now uses `yii\mutex\MysqlMutex` or `yii\mutex\PgsqlMutex` for mutex locking by default.
- It’s now possible to use aliases when eager-loading elements via GraphQL. ([#5481](https://github.com/craftcms/cms/issues/5481))

### Deprecated
- Deprecated `craft\helpers\App::mutexConfig()`.
Expand Down
36 changes: 22 additions & 14 deletions src/gql/ElementQueryConditionBuilder.php
Expand Up @@ -90,31 +90,32 @@ public function extractQueryConditions(FieldInterface $startingParentField = nul
}
}

// Parse everything else
foreach ($eagerLoadingRules as $element => $parameters) {
// Don't need these anymore
if (StringHelper::endsWith($element, '@' . Gql::GRAPHQL_COUNT_FIELD)) {
continue;
}

// If this element was flagged for `withCount`, add it to parameters
if (!empty($relationCountFields[$element])) {
$parameters['count'] = true;
}

if ($element == 'withTransforms') {
// `withTransforms` get loaded using the `withTransforms` method.
if ($element === 'withTransforms') {
$extractedConditions['withTransforms'] = $parameters;
continue;
}

// Just dump it all in where it belongs.
if (empty($parameters)) {
$eagerLoadConditions[] = $element;
$extractedConditions['with'][] = $element;
} else {
$eagerLoadConditions[] = [$element, $parameters];
$extractedConditions['with'][] = [$element, $parameters];
}
}

if (!empty($eagerLoadConditions)) {
$extractedConditions['with'] = $eagerLoadConditions;
}

return $extractedConditions;
}

Expand Down Expand Up @@ -299,7 +300,6 @@ private function _traverseAndExtractRules(Node $parentNode, $prefix = '', $conte
$nodeArguments['withTransforms'] = array_merge_recursive($nodeArguments['withTransforms'], $transformEagerLoadArguments);
}


// If this a custom Craft content field
if ($craftContentField) {
/** @var EagerLoadingFieldInterface $craftContentField */
Expand Down Expand Up @@ -337,24 +337,32 @@ private function _traverseAndExtractRules(Node $parentNode, $prefix = '', $conte
}
}

$alias = (!(empty($subNode->alias)) && !empty($subNode->alias->value)) ? $subNode->alias->value : null;

// If they're angling for the count field, alias it so each count field gets their own eager-load arguments.
if ($nodeName == Gql::GRAPHQL_COUNT_FIELD) {
if (!empty($subNode->alias) && !empty($subNode->alias->value)) {
$nodeName = $subNode->alias->value . '@' . $nodeName;
if ($nodeName === Gql::GRAPHQL_COUNT_FIELD) {
if ($alias) {
$nodeName = $alias . '@' . Gql::GRAPHQL_COUNT_FIELD;
} else {
// Just re-use the node name, then.
$nodeName .= '@' . $nodeName;
$nodeName .= '@' . Gql::GRAPHQL_COUNT_FIELD;
}
}

$nodeKey = $alias ? $nodeName . ' as ' . $alias : $nodeName;

// Add this to the eager loading list.
if (!$transformableAssetProperty) {
$eagerLoadNodes[$prefix . $nodeName] = array_key_exists($prefix . $nodeName, $eagerLoadNodes) ? array_merge_recursive($eagerLoadNodes[$prefix . $nodeName], $arguments) : $arguments;
$eagerLoadNodes[$prefix . $nodeKey] = array_key_exists($prefix . $nodeKey, $eagerLoadNodes) ? array_merge_recursive($eagerLoadNodes[$prefix . $nodeKey], $arguments) : $arguments;
}

// If it has any more selections, build the prefix further and proceed in a recursive manner
if (!empty($subNode->selectionSet)) {
$traversePrefix = $prefix . ($craftContentField ? $craftContentField->handle : 'children');
if ($alias) {
$traversePrefix = $prefix . $alias;
} else {
$traversePrefix = $prefix . ($craftContentField ? $craftContentField->handle : 'children');
}

if ($craftContentField) {
// Relational fields should reset context to global.
Expand Down
3 changes: 2 additions & 1 deletion src/gql/base/ObjectType.php
Expand Up @@ -65,7 +65,8 @@ public function resolveWithDirectives($source, $arguments, $context, ResolveInfo
*/
protected function resolve($source, $arguments, $context, ResolveInfo $resolveInfo)
{
$result = $source->{$resolveInfo->fieldName};
$fieldName = is_array($resolveInfo->path) ? array_slice($resolveInfo->path, -1)[0] : $resolveInfo->fieldName;
$result = $source->$fieldName;

if ($result instanceof ElementQueryInterface) {
return $result->all();
Expand Down

0 comments on commit 04af22c

Please sign in to comment.