Skip to content

Commit 76864c6

Browse files
Merging latest and resolving conflicts
2 parents f8e6a0e + cdfe4e5 commit 76864c6

File tree

12 files changed

+253
-30
lines changed

12 files changed

+253
-30
lines changed

CHANGELOG.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,19 @@
22

33
All notable changes to `WP Curate` will be documented in this file.
44

5-
## 0.1.0 - 202X-XX-XX
5+
## 1.3.0 - 2023-10-26
6+
7+
- Only show the blocks and register the meta on supported post types.
8+
- Supported post types defaults to all Block Editor post types, but can be filtered by filtering `wp_curate_supported_post_types`.
9+
10+
## 1.2.0 - 2023-10-26
11+
12+
- Adds support for AND/OR operators in the Query Parameters, giving more control over what posts to show.
13+
14+
## 1.1.0 - 2023-09-21
15+
16+
- Bug fix: prevents error if post type does not support meta.
17+
18+
## 1.0.0 - 2023-09-19
619

720
- Initial release

blocks/post/index.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,17 @@
55
* @package wp-curate
66
*/
77

8+
use Alley\WP\WP_Curate\Supported_Post_Types;
9+
810
/**
911
* Registers the wp-curate/post block using the metadata loaded from the `block.json` file.
1012
*/
1113
function wp_curate_post_block_init(): void {
14+
$supported_post_types = new Supported_Post_Types();
15+
if ( ! in_array( $supported_post_types->get_current_post_type(), $supported_post_types->get_supported_post_types(), true ) ) {
16+
return;
17+
}
18+
1219
// Register the block by passing the location of block.json.
1320
register_block_type(
1421
__DIR__

blocks/query/block.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,26 @@
7474
"type": "array"
7575
},
7676
"type": "object"
77+
},
78+
"termRelations": {
79+
"default": {},
80+
"items": {
81+
"default": "AND",
82+
"enum": [
83+
"AND",
84+
"OR"
85+
],
86+
"type": "string"
87+
},
88+
"type": "object"
89+
},
90+
"taxRelation": {
91+
"default": "AND",
92+
"enum": [
93+
"AND",
94+
"OR"
95+
],
96+
"type": "string"
7797
}
7898
}
7999
}

blocks/query/edit.tsx

Lines changed: 63 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
PanelRow,
1010
RadioControl,
1111
RangeControl,
12+
SelectControl,
1213
TextControl,
1314
} from '@wordpress/components';
1415
import { useSelect } from '@wordpress/data';
@@ -35,6 +36,8 @@ import {
3536
mainDedupe,
3637
} from '../../services/deduplicate';
3738

39+
import buildTermQueryArgs from '../../services/buildTermQueryArgs';
40+
3841
import './index.scss';
3942

4043
interface Window {
@@ -64,6 +67,8 @@ export default function Edit({
6467
postTypes = ['post'],
6568
searchTerm = '',
6669
terms = {},
70+
termRelations = {},
71+
taxRelation = 'AND',
6772
},
6873
setAttributes,
6974
}: EditProps) {
@@ -74,6 +79,17 @@ export default function Edit({
7479
} = {},
7580
} = (window as any as Window);
7681

82+
const andOrOptions = [
83+
{
84+
label: __('AND', 'wp-curate'),
85+
value: 'AND',
86+
},
87+
{
88+
label: __('OR', 'wp-curate'),
89+
value: 'OR',
90+
},
91+
];
92+
7793
// @ts-ignore
7894
const [isPostDeduplicating, postTypeObject] = useSelect(
7995
(select) => {
@@ -98,17 +114,15 @@ export default function Edit({
98114
const [availableTaxonomies, setAvailableTaxonomies] = useState<Taxonomies>({});
99115
const [availableTypes, setAvailableTypes] = useState<Types>({});
100116

101-
let termQueryArgs = '';
102-
if (Object.keys(availableTaxonomies).length > 0) {
103-
allowedTaxonomies.forEach((taxonomy) => {
104-
if (terms[taxonomy]?.length > 0) {
105-
const restBase = availableTaxonomies[taxonomy].rest_base;
106-
if (restBase) {
107-
termQueryArgs += `&${restBase}=${terms[taxonomy].map((term) => term.id).join(',')}`;
108-
}
109-
}
110-
});
111-
}
117+
const taxCount = allowedTaxonomies.filter((taxonomy: string) => terms[taxonomy]?.length > 0).length; // eslint-disable-line max-len
118+
119+
const termQueryArgs = buildTermQueryArgs(
120+
allowedTaxonomies,
121+
terms,
122+
availableTaxonomies,
123+
termRelations,
124+
taxRelation,
125+
);
112126

113127
const manualPostIds = manualPosts.map((post) => (post ?? null)).join(',');
114128
const postTypeString = postTypes.join(',');
@@ -148,7 +162,7 @@ export default function Edit({
148162
per_page: 20,
149163
},
150164
);
151-
path += termQueryArgs;
165+
path += `&${termQueryArgs}`;
152166

153167
apiFetch({
154168
path,
@@ -205,6 +219,14 @@ export default function Edit({
205219
setAttributes({ terms: newTermAttrs });
206220
});
207221

222+
const setTermRelation = ((type: string, relation: string) => {
223+
const newTermRelationAttrs = {
224+
...termRelations,
225+
[type]: relation,
226+
};
227+
setAttributes({ termRelations: newTermRelationAttrs });
228+
});
229+
208230
const setNumberOfPosts = (newValue?: number) => {
209231
setAttributes({
210232
numberOfPosts: newValue,
@@ -286,11 +308,13 @@ export default function Edit({
286308
className="manual-posts"
287309
>
288310
{manualPosts.map((_post, index) => (
289-
<PanelRow className={classnames(
290-
'manual-posts__container',
291-
{ 'manual-posts__container--selected': manualPosts[index] },
292-
)}
293-
key={index}
311+
<PanelRow
312+
// eslint-disable-next-line react/no-array-index-key
313+
key={index}
314+
className={classnames(
315+
'manual-posts__container',
316+
{ 'manual-posts__container--selected': manualPosts[index] },
317+
)}
294318
>
295319
<span className="manual-posts__counter">{index + 1}</span>
296320
<PostPicker
@@ -325,9 +349,31 @@ export default function Edit({
325349
onSelect={(newCategories: Term[]) => setTerms(taxonomy, newCategories)}
326350
multiple
327351
/>
352+
{terms[taxonomy]?.length > 1 ? (
353+
<SelectControl
354+
label={sprintf(
355+
__('%s Relation', 'wp-curate'),
356+
availableTaxonomies[taxonomy].name || taxonomy,
357+
)}
358+
help={__('AND: Posts must have all selected terms. OR: Posts may have one or more selected terms.', 'wp-curate')}
359+
options={andOrOptions}
360+
onChange={(newValue) => setTermRelation(taxonomy, newValue)}
361+
value={termRelations[taxonomy] ?? 'OR'}
362+
/>
363+
) : null}
364+
<hr />
328365
</Fragment>
329366
))
330367
) : null}
368+
{taxCount > 1 ? (
369+
<SelectControl
370+
label={__('Taxonomy Relation', 'wp-curate')}
371+
help={__('AND: Posts must meet all selected taxonomy requirements. OR: Posts may have meet one or more selected taxonomy requirements.', 'wp-curate')}
372+
options={andOrOptions}
373+
onChange={(newValue) => setAttributes({ taxRelation: newValue })}
374+
value={taxRelation}
375+
/>
376+
) : null }
331377
<TextControl
332378
label={__('Search Term', 'wp-curate')}
333379
onChange={(next) => setAttributes({ searchTerm: next })}

blocks/query/index.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
* @package wp-curate
66
*/
77

8+
use Alley\WP\WP_Curate\Supported_Post_Types;
9+
810
/**
911
* Registers the block using the metadata loaded from the `block.json` file.
1012
* Behind the scenes, it registers also all assets so they can be enqueued
@@ -13,6 +15,11 @@
1315
* @see https://developer.wordpress.org/reference/functions/register_block_type/
1416
*/
1517
function wp_curate_query_block_init(): void {
18+
$supported_post_types = new Supported_Post_Types();
19+
if ( ! in_array( $supported_post_types->get_current_post_type(), $supported_post_types->get_supported_post_types(), true ) ) {
20+
return;
21+
}
22+
1623
// Register the block by passing the location of block.json.
1724
register_block_type(
1825
__DIR__,

blocks/query/types.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ interface EditProps {
1515
terms?: {
1616
[key: string]: any[];
1717
};
18+
termRelations?: {
19+
[key: string]: string;
20+
};
21+
taxRelation?: string;
1822
};
1923
setAttributes: (attributes: any) => void;
2024
}

config/post-meta.json

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +0,0 @@
1-
{
2-
"wp_curate_deduplication": {
3-
"post_types": [
4-
"all"
5-
],
6-
"type": "boolean"
7-
}
8-
}

services/buildTermQueryArgs/index.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
interface Types {
2+
[key: string]: {
3+
name: string;
4+
slug: string;
5+
rest_base: string;
6+
};
7+
}
8+
9+
/**
10+
* Builds the term query args for the WP REST API.
11+
*
12+
* @param string[] allowedTaxonomies The list of allowed taxonomies.
13+
* @param { [key: string]: any[] } terms The selected terms.
14+
* @param { [key: string]: any[] } availableTaxonomies The available taxonomies.
15+
* @param { [key: string]: string } termRelations The AND/OR relation used for each taxonomy.
16+
* @param string taxRelation The AND/OR relation used for all the terms.
17+
* @returns string The term query args.
18+
*/
19+
export default function buildTermQueryArgs(
20+
allowedTaxonomies: string[],
21+
terms: { [key: string]: any[] },
22+
availableTaxonomies: Types,
23+
termRelations: { [key: string]: string },
24+
taxRelation: string,
25+
): string {
26+
const taxCount = allowedTaxonomies.filter((taxonomy: string) => terms[taxonomy]?.length > 0).length; // eslint-disable-line max-len
27+
28+
const termQueryArgs: string[] = [];
29+
if (Object.keys(availableTaxonomies).length > 0) {
30+
allowedTaxonomies.forEach((taxonomy) => {
31+
if (terms[taxonomy]?.length > 0) {
32+
const restBase = availableTaxonomies[taxonomy].rest_base;
33+
if (restBase) {
34+
termQueryArgs.push(`${restBase}[terms]=${terms[taxonomy].map((term) => term.id).join(',')}`);
35+
if (termRelations[taxonomy] !== '' && typeof termRelations[taxonomy] !== 'undefined') {
36+
termQueryArgs.push(`${restBase}[operator]=${termRelations[taxonomy]}`);
37+
}
38+
}
39+
}
40+
});
41+
if (taxCount > 1) {
42+
termQueryArgs.push(`tax_relation=${taxRelation}`);
43+
}
44+
}
45+
return termQueryArgs.join('&');
46+
}

services/deduplicate/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,13 +121,13 @@ export function mainDedupe() {
121121
queryBlocks.forEach((queryBlock) => {
122122
const { attributes } = queryBlock;
123123
const {
124-
backfillPosts = [],
124+
backfillPosts = null,
125125
deduplication = 'inherit',
126126
posts = [],
127127
numberOfPosts = 5,
128128
postTypes = ['post'],
129129
} = attributes;
130-
if (!backfillPosts.length) {
130+
if (!backfillPosts) {
131131
return;
132132
}
133133
const postTypeString = postTypes.join(',');

src/class-plugin-curated-posts.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,15 @@ public function with_query_context( array $context, array $attributes, WP_Block_
5151

5252
if ( isset( $attributes['terms'] ) && is_array( $attributes['terms'] ) && count( $attributes['terms'] ) > 0 ) {
5353
$args['tax_query'] = [ // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query
54-
'relation' => 'AND',
54+
'relation' => $attributes['taxRelation'] ?? 'AND',
5555
];
5656

5757
foreach ( $attributes['terms'] as $taxonomy => $terms ) {
5858
if ( taxonomy_exists( $taxonomy ) && is_array( $terms ) && count( $terms ) > 0 ) {
5959
$args['tax_query'][] = [
6060
'taxonomy' => $taxonomy,
6161
'terms' => array_column( $terms, 'id' ),
62+
'operator' => is_array( $attributes['termRelations'] ) ? $attributes['termRelations'][ $taxonomy ] ?? 'AND' : 'AND',
6263
];
6364
}
6465
}

0 commit comments

Comments
 (0)