Skip to content

Support aliases for selection set and arguments for scalar selected fields. #15

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

Closed
wants to merge 1 commit into from
Closed
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
31 changes: 26 additions & 5 deletions src/FieldTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,35 @@ trait FieldTrait
public function setSelectionSet(array $selectionSet)
Copy link
Owner

Choose a reason for hiding this comment

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

@actionm I kind of don't understand why this change is necessary? 🤔
Is it because you want to add the feature of selecting fields with aliases and arguments through the Query class? It's not required for selecting one field through the AbstractQueryBuilder as it converts all selected fields into string before the selection set is set in the query class. Or maybe I'm missing something here.

{
$nonStringsFields = array_filter($selectionSet, function($element) {
return !is_string($element) && !$element instanceof Query && !$element instanceof InlineFragment;
return !is_string($element) && !is_array($element) && !$element instanceof Query && !$element instanceof InlineFragment;
});

if (!empty($nonStringsFields)) {
throw new InvalidSelectionException(
'One or more of the selection fields provided is not of type string or Query'
'One or more of the selection fields provided is not of type string, array or Query'
);
}

// SelectionSet with arguments
foreach ($selectionSet as $element => $arguments) {

if (is_array($arguments) && count($arguments)) {

$params = '';
Copy link
Owner

Choose a reason for hiding this comment

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

@actionm We already have a method that converts an arguments array into a string representation, we should figure out how to re-use it here rather than duplicate it. It's in the Query class.

foreach ($arguments as $param => $val) {
if (is_string($val)) {
$params .= " $param : \"$val\" ";
}
}

if (!empty($params)) {
$selectedField = ' ' . $element . " ($params)";
$selectionSet[] = $selectedField;
unset($selectionSet[$element]);
}
}
}

$this->selectionSet = $selectionSet;

return $this;
Expand All @@ -40,15 +61,15 @@ public function setSelectionSet(array $selectionSet)
*/
protected function constructSelectionSet(): string
{
$attributesString = " {\n";
$attributesString = " {" . PHP_EOL;
$first = true;
foreach ($this->selectionSet as $attribute) {

// Append empty line at the beginning if it's not the first item on the list
if ($first) {
$first = false;
} else {
$attributesString .= "\n";
$attributesString .= PHP_EOL;
}

// If query is included in attributes set as a nested query
Expand All @@ -59,7 +80,7 @@ protected function constructSelectionSet(): string
// Append attribute to returned attributes list
$attributesString .= $attribute;
}
$attributesString .= "\n}";
$attributesString .= PHP_EOL . "}";

return $attributesString;
}
Expand Down
2 changes: 1 addition & 1 deletion src/Query.php
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ public function __toString()
{
$queryFormat = static::QUERY_FORMAT;
if (!$this->isNested && $this->fieldName !== static::OPERATION_TYPE) {
$queryFormat = $this->generateSignature() . " {\n" . static::QUERY_FORMAT . "\n}";
$queryFormat = $this->generateSignature() . " {" . PHP_EOL . static::QUERY_FORMAT . PHP_EOL. "}";
}
$argumentsString = $this->constructArguments();
$selectionSetString = $this->constructSelectionSet();
Expand Down
19 changes: 18 additions & 1 deletion src/QueryBuilder/AbstractQueryBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,16 +74,33 @@ public function getQuery(): Query
/**
* @param string|QueryBuilder|Query $selectedField
*
* @param string|null $alias
* @param array $arguments
* @return $this
*/
protected function selectField($selectedField)
protected function selectField($selectedField, string $alias = null, array $arguments = [])
{
if (
is_string($selectedField)
|| $selectedField instanceof AbstractQueryBuilder
|| $selectedField instanceof Query
|| $selectedField instanceof InlineFragment
) {

// Set an alias for selectedField
$selectedField = ($alias) ? $alias .':'. $selectedField : $selectedField;

// Add arguments for selectedField
if (is_array($arguments) && count($arguments)) {

$params = '';
foreach ($arguments as $k => $v) {
Copy link
Owner

Choose a reason for hiding this comment

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

@actionm Another instance of code duplication for the same functionality.

$params.= " $k : \"$v\" ";
}
$selectedField .= " ($params)";
}


$this->selectionSet[] = $selectedField;
}

Expand Down
6 changes: 4 additions & 2 deletions src/QueryBuilder/QueryBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@ class QueryBuilder extends AbstractQueryBuilder
*
* @param Query|QueryBuilder|string $selectedField
*
* @param string|null $alias
* @param array $arguments
* @return AbstractQueryBuilder|QueryBuilder
*/
public function selectField($selectedField)
public function selectField($selectedField, string $alias = null, array $arguments = [])
{
return parent::selectField($selectedField);
return parent::selectField($selectedField, $alias, $arguments);
}

/**
Expand Down
69 changes: 69 additions & 0 deletions tests/QueryBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,75 @@ public function testEmptySelectionSet()
$this->queryBuilder->getQuery();
}


/**
* @covers \GraphQL\QueryBuilder\QueryBuilder::__construct
* @covers \GraphQL\QueryBuilder\AbstractQueryBuilder::__construct
*/
public function testSelectFieldAlias()
{
$builder = new QueryBuilder('Object');
$builder->selectField('field_one', 'fieldAlias');
$this->assertEquals(
'query {
Object {
fieldAlias:field_one
}
}',
(string) $builder->getQuery()
);
}

/**
* @covers \GraphQL\QueryBuilder\QueryBuilder::__construct
* @covers \GraphQL\QueryBuilder\AbstractQueryBuilder::__construct
*/
public function testSelectFieldAliasWithArguments()
{
$builder = new QueryBuilder('Object');
$builder->selectField('field_one', 'fieldAlias', ['param1' => 'val1', 'param2' => 'val2' ]);
$this->assertEquals(
'query {
Object {
fieldAlias:field_one ( param1 : "val1" param2 : "val2" )
}
}',
(string) $builder->getQuery()
);

}
Copy link
Owner

Choose a reason for hiding this comment

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

@actionm We need a test to cover the case of usage of arguments without aliases.


/**
* @covers \GraphQL\QueryBuilder\QueryBuilder::__construct
* @covers \GraphQL\QueryBuilder\AbstractQueryBuilder::__construct
*/
public function testSelectionSetAliasWithArguments()
{
$builder = new QueryBuilder('Object');

$builder->selectField(
(new Query('data'))->setArguments(['some_field' => 'params'])
->setSelectionSet(
[
'aliasId:first_field' => ['param1' => 'val1', 'param2' => 'val2' ],
'second_field' => ['param1' => 'val1', 'param2' => 'val2' ]
])
);

$this->assertEquals(
'query {
Object {
data(some_field: "params") {
aliasId:first_field ( param1 : "val1" param2 : "val2" )
second_field ( param1 : "val1" param2 : "val2" )
}
}
}',
(string) $builder->getQuery()
);


}
Copy link
Owner

Choose a reason for hiding this comment

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

@actionm We need tests for sub-selections (nested queries) with arguments/aliases.

/**
* @covers \GraphQL\QueryBuilder\QueryBuilder::setVariable
* @covers \GraphQL\QueryBuilder\AbstractQueryBuilder::setVariable
Expand Down