Skip to content

Commit e935407

Browse files
authored
Merge pull request #339 from wpengine/feature/180-core-post-terms-fetch-terms
feat: Adds terms querying functionality for the CorePostTerms Block.
2 parents 8bd5bd4 + 03ef8c2 commit e935407

File tree

3 files changed

+276
-0
lines changed

3 files changed

+276
-0
lines changed

.changeset/calm-socks-battle.md

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
---
2+
"@wpengine/wp-graphql-content-blocks": minor
3+
---
4+
5+
Adds support for resolving and returning related term items as a `terms` connection for the CorePostTerms block along with `taxonomy` connection.
6+
Adds support for resolving and returning the `prefix` and `suffix` items within the correspondent fields of the CorePostTerms block.
7+
8+
```graphql
9+
query TestPostTerms($uri: String! = "test-terms") {
10+
nodeByUri(uri: $uri) {
11+
id
12+
uri
13+
... on NodeWithPostEditorBlocks {
14+
editorBlocks {
15+
__typename
16+
... on CorePostTerms {
17+
prefix
18+
suffix
19+
taxonomy {
20+
__typename
21+
node {
22+
__typename
23+
id
24+
name
25+
}
26+
}
27+
terms {
28+
__typename
29+
nodes {
30+
__typename
31+
id
32+
name
33+
}
34+
}
35+
}
36+
}
37+
}
38+
}
39+
}
40+
```

includes/Blocks/CorePostTerms.php

+104
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
<?php
2+
/**
3+
* Core Post Terms Block
4+
*
5+
* @package WPGraphQL\ContentBlocks\Blocks
6+
*/
7+
8+
namespace WPGraphQL\ContentBlocks\Blocks;
9+
10+
use WPGraphQL\AppContext;
11+
use WPGraphQL\ContentBlocks\Registry\Registry;
12+
use WPGraphQL\Data\Connection\TaxonomyConnectionResolver;
13+
use WPGraphQL\Data\Connection\TermObjectConnectionResolver;
14+
use WP_Block_Type;
15+
16+
/**
17+
* Class CorePostTerms.
18+
*/
19+
class CorePostTerms extends Block {
20+
/**
21+
* {@inheritDoc}
22+
*/
23+
public function __construct( WP_Block_Type $block, Registry $block_registry ) {
24+
parent::__construct( $block, $block_registry );
25+
26+
$this->register_fields();
27+
$this->register_connections();
28+
}
29+
30+
/**
31+
* Registers custom fields for the block.
32+
*/
33+
private function register_fields(): void {
34+
register_graphql_fields(
35+
$this->type_name,
36+
[
37+
'prefix' => [
38+
'type' => 'String',
39+
'description' => __( 'Prefix to display before the post terms', 'wp-graphql-content-blocks' ),
40+
'resolve' => static fn ( $block ) => isset( $block['attrs']['prefix'] ) ? (string) $block['attrs']['prefix'] : null,
41+
],
42+
'suffix' => [
43+
'type' => 'String',
44+
'description' => __( 'Suffix to display after the post terms', 'wp-graphql-content-blocks' ),
45+
'resolve' => static fn ( $block ) => isset( $block['attrs']['suffix'] ) ? (string) $block['attrs']['suffix'] : null,
46+
],
47+
]
48+
);
49+
}
50+
51+
/**
52+
* Registers a list of terms field for the block.
53+
*
54+
* @return void
55+
* @throws \Exception
56+
*/
57+
protected function register_connections() {
58+
// Register connection to terms.
59+
register_graphql_connection(
60+
[
61+
'fromType' => $this->type_name,
62+
'toType' => 'TermNode',
63+
'fromFieldName' => 'terms',
64+
'resolve' => static function ( $block, array $args, AppContext $context, $info ) {
65+
$taxonomy = $block['attrs']['term'] ?? null;
66+
if ( empty( $taxonomy ) ) {
67+
return null;
68+
}
69+
70+
$post_id = get_the_ID();
71+
if ( ! $post_id ) {
72+
return null;
73+
}
74+
75+
$args['where']['objectIds'] = $post_id;
76+
$resolver = new TermObjectConnectionResolver( $block, $args, $context, $info, $taxonomy );
77+
78+
return $resolver->get_connection();
79+
},
80+
]
81+
);
82+
83+
// Register connection to the taxonomy.
84+
register_graphql_connection(
85+
[
86+
'fromType' => $this->type_name,
87+
'toType' => 'Taxonomy',
88+
'fromFieldName' => 'taxonomy',
89+
'oneToOne' => true,
90+
'resolve' => static function ( $block, array $args, AppContext $context, $info ) {
91+
$taxonomy = $block['attrs']['term'] ?? null;
92+
if ( empty( $taxonomy ) ) {
93+
return null;
94+
}
95+
96+
$resolver = new TaxonomyConnectionResolver( $block, $args, $context, $info );
97+
$resolver->set_query_arg( 'name', $taxonomy );
98+
99+
return $resolver->one_to_one()->get_connection();
100+
},
101+
]
102+
);
103+
}
104+
}

tests/unit/CorePostTermsTest.php

+132
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
<?php
2+
3+
namespace WPGraphQL\ContentBlocks\Unit;
4+
5+
final class CorePostTermsTest extends PluginTestCase {
6+
7+
/**
8+
* The URI of the post created for the test.
9+
*
10+
* @var string
11+
*/
12+
public $post_uri;
13+
14+
/**
15+
* The ID of the post created for the test.
16+
*
17+
* @var int
18+
*/
19+
public $post_id;
20+
21+
public function setUp(): void {
22+
parent::setUp();
23+
24+
$this->post_id = wp_insert_post(
25+
[
26+
'post_title' => 'Test Terms',
27+
'post_name' => 'test-terms',
28+
'post_content' => '',
29+
'post_status' => 'publish',
30+
]
31+
);
32+
33+
$this->post_uri = get_permalink($this->post_id);
34+
35+
\WPGraphQL::clear_schema();
36+
}
37+
38+
public function tearDown(): void {
39+
wp_delete_post($this->post_id, true);
40+
\WPGraphQL::clear_schema();
41+
42+
parent::tearDown();
43+
}
44+
45+
/**
46+
* Get the updated GraphQL query for the CorePostTerms block.
47+
*/
48+
public function query(): string {
49+
return '
50+
query TestPostTerms($uri: String! = "test-terms") {
51+
nodeByUri(uri: $uri) {
52+
id
53+
uri
54+
... on NodeWithPostEditorBlocks {
55+
editorBlocks {
56+
__typename
57+
... on CorePostTerms {
58+
prefix
59+
suffix
60+
taxonomy {
61+
__typename
62+
node {
63+
__typename
64+
id
65+
name
66+
}
67+
}
68+
terms {
69+
__typename
70+
nodes {
71+
__typename
72+
id
73+
name
74+
}
75+
}
76+
}
77+
}
78+
}
79+
}
80+
}
81+
';
82+
}
83+
84+
/**
85+
* Test that the CorePostTerms block retrieves attributes, taxonomy, and terms correctly.
86+
*/
87+
public function test_retrieve_core_post_terms(): void {
88+
$block_content = '<!-- wp:post-terms {"prefix":"Before","suffix":"After","term":"category"} /-->';
89+
90+
wp_update_post(
91+
[
92+
'ID' => $this->post_id,
93+
'post_content' => $block_content,
94+
]
95+
);
96+
97+
$variables = [ 'uri' => 'test-terms' ];
98+
$query = $this->query();
99+
$actual = graphql(compact('query', 'variables'));
100+
101+
$node = $actual['data']['nodeByUri'];
102+
103+
$this->assertArrayHasKey('editorBlocks', $node);
104+
$this->assertCount(1, $node['editorBlocks']);
105+
106+
$block = $node['editorBlocks'][0];
107+
108+
$this->assertEquals('CorePostTerms', $block['__typename']);
109+
$this->assertEquals('Before', $block['prefix']);
110+
$this->assertEquals('After', $block['suffix']);
111+
112+
$this->assertArrayHasKey('taxonomy', $block);
113+
$this->assertArrayHasKey('node', $block['taxonomy']);
114+
$this->assertArrayHasKey('__typename', $block['taxonomy']['node']);
115+
$this->assertArrayHasKey('id', $block['taxonomy']['node']);
116+
$this->assertArrayHasKey('name', $block['taxonomy']['node']);
117+
118+
$this->assertArrayHasKey('terms', $block);
119+
$this->assertArrayHasKey('nodes', $block['terms']);
120+
$this->assertIsArray($block['terms']['nodes']);
121+
$this->assertEquals('CorePostTermsToTermNodeConnection', $block['terms']['__typename']);
122+
$this->assertEquals('Category', $block['terms']['nodes'][0]['__typename']);
123+
124+
$this->assertArrayHasKey('taxonomy', $block);
125+
$this->assertArrayHasKey('node', $block['taxonomy']);
126+
$this->assertIsArray($block['taxonomy']['node']);
127+
$this->assertEquals('CorePostTermsToTaxonomyConnectionEdge', $block['taxonomy']['__typename']);
128+
$this->assertEquals('category', $block['taxonomy']['node']['name']);
129+
130+
131+
}
132+
}

0 commit comments

Comments
 (0)