Skip to content

Commit

Permalink
fix: backwards pagination and filtering in FormFieldsConnectionResolv…
Browse files Browse the repository at this point in the history
…er (#420)
  • Loading branch information
justlevine authored Jun 2, 2024
1 parent a050062 commit e68b7c0
Show file tree
Hide file tree
Showing 5 changed files with 521 additions and 26 deletions.
88 changes: 73 additions & 15 deletions src/Data/Connection/FormFieldsConnectionResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ protected function loader_name(): string {
*/
public function is_valid_offset( $offset ) {
foreach ( $this->form_fields as $field ) {
if ( $field->id === $offset ) {
if ( (int) $field->id === (int) $offset ) {
return true;
}
}
Expand All @@ -87,7 +87,41 @@ public function get_ids_from_query() {

$ids = [];
foreach ( $queried as $item ) {
$ids[ $item->id ] = $item->id;
$ids[ (int) $item->id ] = $item->id;
}

return $ids;
}

/**
* {@inheritDoc}
*/
public function apply_cursors_to_ids( array $ids ) {
if ( empty( $ids ) ) {
return [];
}
$args = $this->get_args();

// First we slice the array from the front.
if ( ! empty( $args['after'] ) ) {
$offset = $this->get_offset_for_cursor( $args['after'] );
$index = $this->get_array_index_for_offset( $offset, $ids );

if ( false !== $index ) {
// We want to start with the first id after the index.
$ids = array_slice( $ids, $index + 1, null, true );
}
}

// Then we slice the array from the back.
if ( ! empty( $args['before'] ) ) {
$offset = $this->get_offset_for_cursor( $args['before'] );
$index = $this->get_array_index_for_offset( $offset, $ids );

if ( false !== $index ) {
// We want to end with the id before the index.
$ids = array_slice( $ids, 0, $index, true );
}
}

return $ids;
Expand All @@ -97,25 +131,31 @@ public function get_ids_from_query() {
* {@inheritDoc}
*/
protected function prepare_args( array $args ): array {
// Ensure that the ids are an array.
if ( isset( $args['where']['ids'] ) && ! is_array( $args['where']['ids'] ) ) {
$args['where']['ids'] = [ $args['where']['ids'] ];
// Ensure that the ids are an array of ints.
if ( isset( $args['where']['ids'] ) ) {
if ( ! is_array( $args['where']['ids'] ) ) {
$args['where']['ids'] = [ $args['where']['ids'] ];
}

// Sanitize the IDs.
$args['where']['ids'] = array_map( 'absint', $args['where']['ids'] );
}

// Ensure that Admin labels are an array.
if ( isset( $args['where']['adminLabels'] ) && ! is_array( $args['where']['adminLabels'] ) ) {
$args['where']['adminLabels'] = [ $args['where']['adminLabels'] ];
// Ensure that Admin labels are an array of strings.
if ( isset( $args['where']['adminLabels'] ) ) {
if ( ! is_array( $args['where']['adminLabels'] ) ) {
$args['where']['adminLabels'] = [ $args['where']['adminLabels'] ];
}

// Sanitize the Admin labels.
$args['where']['adminLabels'] = array_map( 'sanitize_text_field', $args['where']['adminLabels'] );
}

// Ensure that Field types are an array.
if ( isset( $args['where']['fieldTypes'] ) && ! is_array( $args['where']['fieldTypes'] ) ) {
$args['where']['fieldTypes'] = [ $args['where']['fieldTypes'] ];
// Ensure that Field types are an array of strings.
if ( isset( $args['where']['fieldTypes'] ) ) {
if ( ! is_array( $args['where']['fieldTypes'] ) ) {
$args['where']['fieldTypes'] = [ $args['where']['fieldTypes'] ];
}

// Sanitize the Field types.
$args['where']['fieldTypes'] = array_map( 'sanitize_text_field', $args['where']['fieldTypes'] );
Expand Down Expand Up @@ -149,22 +189,40 @@ protected function query( array $query_args ): array {

// Filter by IDs.
if ( ! empty( $query_args['ids'] ) ) {
$fields = array_filter( $fields, static fn ( $field ) => in_array( (int) $field['id'], $query_args['ids'], true ) );
$fields = array_filter( $fields, static fn ( \GF_Field $field ) => isset( $field->id ) && in_array( (int) $field->id, $query_args['ids'], true ) );
}

// Filter by Admin labels.
if ( ! empty( $query_args['adminLabels'] ) ) {
$fields = array_filter( $fields, static fn ( $field ) => in_array( $field['adminLabel'], $query_args['adminLabels'], true ) );
$fields = array_filter( $fields, static fn ( \GF_Field $field ) => isset( $field->adminLabel ) && in_array( $field->adminLabel, $query_args['adminLabels'], true ) );
}

// Filter by Field types.
if ( ! empty( $query_args['fieldTypes'] ) ) {
$fields = array_filter( $fields, static fn ( $field ) => in_array( $field['type'], $query_args['fieldTypes'], true ) );
$fields = array_filter( $fields, static fn ( \GF_Field $field ) => isset( $field->type ) && in_array( $field->type, $query_args['fieldTypes'], true ) );
}

// Filter by Page number.
$has_page_number = false;
if ( ! empty( $query_args['pageNumber'] ) ) {
$fields = array_filter( $fields, static fn ( $field ) => $query_args['pageNumber'] === (int) $field['pageNumber'] );
$filtered_fields = array_filter(
$fields,
static function ( \GF_Field $field ) use ( $query_args, &$has_page_number ) {
if ( ! isset( $field->pageNumber ) ) {
return false;
}

// Set the flag to true if the page number is found.
$has_page_number = true;

return $query_args['pageNumber'] === (int) $field->pageNumber;
}
);

// Dont use filtered fileds if the form isnt paged.
if ( $has_page_number || 1 < $query_args['pageNumber'] ) {
$fields = $filtered_fields;
}
}

return $fields;
Expand Down
18 changes: 9 additions & 9 deletions tests/wpunit/EmailFieldTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,15 +70,15 @@ public function generate_fields(): array {

// Mimic the Form Field model.
// $field->inputs = [
// [
// 'autocompleteAttribute' => $field->autocompleteAttribute ?? null,
// 'defaultValue' => $field->defaultValue ?? null,
// 'customLabel' => $field->customLabel ?? null,
// 'id' => $field->id ?? null,
// 'label' => $field->label ?? null,
// 'name' => $field->inputName ?? null,
// 'placeholder' => $field->placeholder ?? null,
// ]
// [
// 'autocompleteAttribute' => $field->autocompleteAttribute ?? null,
// 'defaultValue' => $field->defaultValue ?? null,
// 'customLabel' => $field->customLabel ?? null,
// 'id' => $field->id ?? null,
// 'label' => $field->label ?? null,
// 'name' => $field->inputName ?? null,
// 'placeholder' => $field->placeholder ?? null,
// ]
// ];

return [ $field ];
Expand Down
2 changes: 1 addition & 1 deletion tests/wpunit/EmailFieldWithConfirmationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public function field_helper() {
* Generates the form fields from factory. Must be wrappend in an array.
*/
public function generate_fields(): array {
$field = $this->factory->field->create(
$field = $this->factory->field->create(
array_merge(
$this->property_helper->values,
[ 'emailConfirmEnabled' => true ],
Expand Down
2 changes: 1 addition & 1 deletion tests/wpunit/FormConnectionQueriesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ public function testBackwardPagination() {
$this->assertEquals( true, $actual['data']['gfForms']['pageInfo']['hasNextPage'] );

/**
* Test the last two results are equal to `last:2`.
* Test the last two results are equal to `first:2`.
*/
$variables = [
'first' => 2,
Expand Down
Loading

0 comments on commit e68b7c0

Please sign in to comment.