Skip to content

Commit

Permalink
Merge pull request #42 from AxeWP/dev/get-graphql-allowed-facets
Browse files Browse the repository at this point in the history
dev: refactor to use `get_graphql_allowed_facets()`
  • Loading branch information
justlevine authored Jan 12, 2023
2 parents 6414586 + a2ea791 commit f1d60b5
Show file tree
Hide file tree
Showing 5 changed files with 223 additions and 122 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@
- chore: switch `poolshark/wp-graphql-stubs` for `axepress/wp-graphql-stubs`
- chore: stub `FWP()` and FacetWP class properties.
- chore: change stubfile extensions to `.php`.
- dev: use `camelCase` for FacetQueryArgs field names by default. Fields using `snake_case` have been deprecated and will be removed in a future version.
- dev: add `get_graphql_allowed_facets()` access function.
- dev: allow for (programmatically) overwriting GraphQL-specific field properties.
- dev: refactor facet input types to use the `graphql_type` config property generated by `FacetRegistry::get_facet_input_type()`.
- dev: add the following WordPress filters: `graphql_facetwp_facet_input_type`.
- tests: chang `FWPGraphQLTestCase.php::register_facet()` add facet instead of replace it.

## v.0.4.0
This _major_ release refactors the underlying PHP codebase, bringing with it support for the latest versions of WPGraphQL and FacetWP. Care has been taken to ensure there are _no breaking changes_ to the GraphQL schema.
Expand Down
11 changes: 11 additions & 0 deletions access-functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,14 @@ function() use ( $type_name ) {
);
}
}

if ( ! function_exists( 'get_graphql_allowed_facets' ) ) {
/**
* Get the facets that are allowed to be queried via GraphQL.
*
* @since @todo
*/
function get_graphql_allowed_facets() : array {
return FacetRegistry::get_allowed_facets();
}
}
249 changes: 131 additions & 118 deletions src/Registry/FacetRegistry.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

namespace WPGraphQL\FacetWP\Registry;

use WPGraphQL;
use WPGraphQL\Connection\PostObjects;
use WPGraphQL\Data\Connection\PostObjectConnectionResolver;
use WPGraphQL\FacetWP\Type\Input;
Expand All @@ -17,6 +18,113 @@
*/
class FacetRegistry {

/**
* The facet configs to register to WPGraphQL
*
* @var ?array
*/
protected static $facets;

/**
* Gets the facet configs to be registered to WPGraphQL.
*/
public static function get_allowed_facets() : array {
if ( ! isset( self::$facets ) ) {
$configs = FWP()->helper->get_facets();

// Add GraphQL properties to each facet config.
foreach ( $configs as $key => $config ) {
// @todo set these on the backend.
$configs[ $key ]['graphql_field_name'] = $config['graphql_field_name'] ?? graphql_format_field_name( $config['name'] );
$configs[ $key ]['show_in_graphql'] = $config['show_in_graphql'] ?? true;
$configs[ $key ]['graphql_type'] = self::get_facet_input_type( $config );
}

self::$facets = array_values(
array_filter(
$configs,
function( $config ) {
return $config['show_in_graphql'];
}
)
);
}

return self::$facets;
}

/**
* Gets the GraphQL input type for a facet.
*
* @param array $config The facet config.
*
* @return string|array
*
* @since @todo
*/
public static function get_facet_input_type( array $config ) {
// The default facet type is a list of strings.
$type = [ 'list_of' => 'String' ];

switch ( $config['type'] ) {
case 'fselect':
// Single string for single fSelect.
if ( 'yes' === $config['multiple'] ) {
break;
}
// Continuing...
case 'radio':
case 'search':
// Single string.
$type = 'String';

break;
case 'date_range':
// Custom payload.
$type = Input\DateRangeArgs::$type;

break;
case 'number_range':
// Custom payload.
$type = Input\NumberRangeArgs::$type;

break;
case 'slider':
// Custom payload.
$type = Input\SliderArgs::$type;

break;
case 'proximity':
// Custom payload.
$type = Input\ProximityArgs::$type;

break;
case 'rating':
// Single Int.
$type = 'Int';

break;
case 'autocomplete':
case 'checkboxes':
case 'dropdown':
case 'hierarchy':
default:
// String array - default.
break;
}

/**
* Filter the GraphQL input type for a facet.
*
* @param string|array $input_type The GraphQL Input type name to use.
* @param string $facet_type The FacetWP facet type.
* @param array $facet_config The FacetWP facet config.
*/
$type = apply_filters( 'graphql_facetwp_facet_input_type', $type, $config['type'], $config );

return $type;
}

/**
* Register WPGraphQL Facet query.
*
Expand Down Expand Up @@ -163,71 +271,7 @@ private static function register_input_arg_types( array $facet_config ) : void {

$use_graphql_pagination = self::use_graphql_pagination();

$facets = FWP()->helper->get_facets();

$graphql_fields = array_reduce(
$facets,
function ( $prev, $cur ) {
if ( $cur && $cur['name'] ) {
$type = [
'list_of' => 'String',
];

switch ( $cur['type'] ) {
case 'fselect':
// Single string for single fSelect.
if ( 'yes' === $cur['multiple'] ) {
break;
}
// Continuing...
case 'radio':
case 'search':
// Single string.
$type = 'String';
break;
case 'date_range':
// Custom payload.
$type = Input\DateRangeArgs::$type;
break;
case 'number_range':
// Custom payload.
$type = Input\NumberRangeArgs::$type;
break;
case 'slider':
// Custom payload.
$type = Input\SliderArgs::$type;
break;
case 'proximity':
// Custom payload.
$type = Input\ProximityArgs::$type;
break;
case 'rating':
// Single Int.
$type = 'Int';
break;
case 'autocomplete':
case 'checkboxes':
case 'dropdown':
case 'hierarchy':
default:
// String array - default.
break;
}

$prev[ $cur['name'] ] = [
'type' => $type,
'description' => sprintf(
// translators: The current Facet label.
__( '%s facet query', 'wpgraphql-facetwp' ),
$cur['label']
),
];
}

return $prev;
},
[]
);
$facets = self::get_allowed_facets();

register_graphql_input_type(
'FacetQueryArgs',
Expand All @@ -240,65 +284,34 @@ function ( $prev, $cur ) {
'fields' => array_reduce(
$facets,
function ( $prev, $cur ) {
if ( $cur && $cur['name'] ) {
$type = [
'list_of' => 'String',
];
if ( empty( $cur['graphql_field_name'] ) ) {
return $prev;
}

switch ( $cur['type'] ) {
case 'fselect':
// Single string for single fSelect.
if ( 'yes' === $cur['multiple'] ) {
break;
}
// Continuing...
case 'radio':
case 'search':
// Single string.
$type = 'String';

break;
case 'date_range':
// Custom payload.
$type = Input\DateRangeArgs::$type;

break;
case 'number_range':
// Custom payload.
$type = Input\NumberRangeArgs::$type;

break;
case 'slider':
// Custom payload.
$type = Input\SliderArgs::$type;

break;
case 'proximity':
// Custom payload.
$type = Input\ProximityArgs::$type;

break;
case 'rating':
// Single Int.
$type = 'Int';

break;
case 'autocomplete':
case 'checkboxes':
case 'dropdown':
case 'hierarchy':
default:
// String array - default.
break;
}
// Add the field config.
$prev[ $cur['graphql_field_name'] ] = [
'type' => $cur['graphql_type'],
'description' => sprintf(
// translators: The current Facet label.
__( '%s facet query', 'wpgraphql-facetwp' ),
$cur['label']
),
];

// Maybe add the deprecate type name.
if ( $cur['name'] !== $cur['graphql_field_name'] ) {
$prev[ $cur['name'] ] = [
'type' => $type,
'description' => sprintf(
'type' => $cur['graphql_type'],
'description' => sprintf(
// translators: The current Facet label.
__( '%s facet query', 'wpgraphql-facetwp' ),
__( 'DEPRECATED since @todo', 'wpgraphql-facetwp' ),
$cur['label']
),
'deprecationReason' => sprintf(
// translators: The the GraphQL field name.
__( 'Use %s instead.', 'wpgraphql-facetwp' ),
$cur['graphql_field_name']
),
];
}

Expand Down
15 changes: 12 additions & 3 deletions tests/_support/TestCase/FWPGraphQLTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

namespace Tests\WPGraphQL\FacetWP\TestCase;

use ReflectionProperty;

/**
* Class - GraphQLTestCase
*/
Expand All @@ -28,6 +30,7 @@ public function setUp() : void {
*/
public function tearDown(): void {
$this->clearFacets();
$this->clearSchema();
// Then...
parent::tearDown();
}
Expand All @@ -46,15 +49,21 @@ public function register_facet( array $config = [] ) : void {
'ghosts' => 'no',
'preserve_ghosts' => 'no',
'operator' => 'and',
'soft_limit' => '5'
'soft_limit' => '5',
'show_in_graphql' => true,
];

$config = array_merge( $defaults, $config );

FWP()->helper->settings['facets'] = [ $config ];
FWP()->helper->settings['facets'][] = $config;
}

public function clearFacets() : void {
FWP()->helper->settings['facets'] = [];
unset( FWP()->helper->settings['facets'] );

// Clear the FacetRegistry::$facets property.
$facets_property = new ReflectionProperty( 'WPGraphQL\FacetWP\Registry\FacetRegistry', 'facets' );
$facets_property->setAccessible( true );
$facets_property->setValue( null, null );
}
}
Loading

0 comments on commit f1d60b5

Please sign in to comment.