PluginProbe ʕ •ᴥ•ʔ
AlphaListing / trunk
AlphaListing vtrunk
trunk 4.3.4 4.3.5 4.3.6 4.3.7 4.4.0
alphalisting / src / Shortcode / QueryParts / ExcludeTerms.php
alphalisting / src / Shortcode / QueryParts Last commit date
Alphabet.php 9 months ago BackToTop.php 1 month ago ColumnGap.php 1 month ago ColumnWidth.php 1 month ago Columns.php 1 month ago ExcludePosts.php 9 months ago ExcludeTerms.php 1 month ago HideEmptyTerms.php 9 months ago HideEmpty_Deprecated.php 9 months ago InstanceId.php 9 months ago ParentPost.php 9 months ago ParentTermCommon.php 9 months ago ParentTermId.php 9 months ago ParentTermSlugOrId.php 9 months ago PostType.php 1 month ago PostsTerms.php 9 months ago SymbolsFirst.php 9 months ago Taxonomy.php 9 months ago TermsCommon.php 9 months ago TermsTerms.php 9 months ago
ExcludeTerms.php
126 lines
1 <?php
2 /**
3 * Exclude Terms Query Part.
4 *
5 * @package alphalisting
6 */
7
8 declare(strict_types=1);
9
10 namespace eslin87\AlphaListing\Shortcode\QueryParts;
11
12 if (!defined("ABSPATH")) {
13 exit();
14 }
15
16 use eslin87\AlphaListing\Shortcode\Extension;
17 use eslin87\AlphaListing\Strings;
18
19 /**
20 * Exclude Terms Query Part extension
21 */
22 class ExcludeTerms extends Extension {
23 /**
24 * The attribute for this Query Part.
25 *
26 * @since 4.0.0
27 * @var string
28 */
29 public $attribute_name = "exclude-terms";
30
31 /**
32 * The types of listing this shortcode extension may be used with.
33 *
34 * @since 4.0.0
35 * @var array<string>
36 */
37 public $display_types = ["posts", "terms"];
38
39 /**
40 * Update the query with this extension's additional configuration.
41 *
42 * @param \AlphaListing\Query $query The query.
43 * @param string $display The display/query type.
44 * @param string $key The name of the attribute.
45 * @param mixed $value The shortcode attribute value.
46 * @param array $attributes The complete set of shortcode attributes.
47 * @return mixed The updated query.
48 */
49 public function shortcode_query_for_display_and_attribute( $query, string $display, string $key, $value, array $attributes) {
50
51 $exclude_terms = $this->normalize_term_ids($value);
52
53 if (empty($exclude_terms)) {
54 return $query;
55 }
56
57 if ("terms" === $display) {
58 $existing_exclusions = [];
59
60 if (isset($query["exclude"])) {
61 $existing_exclusions = $this->normalize_term_ids(
62 $query["exclude"],
63 );
64 }
65
66 $query["exclude"] = array_values(
67 array_unique(array_merge($existing_exclusions, $exclude_terms)),
68 );
69
70 return $query;
71 }
72
73 $taxonomy = isset($attributes["taxonomy"])
74 ? $attributes["taxonomy"]
75 : "category";
76
77 $exclude_clause = [
78 "taxonomy" => $taxonomy,
79 "field" => "term_id",
80 "terms" => $exclude_terms,
81 "operator" => "NOT IN",
82 ];
83
84 $tax_query = isset($query["tax_query"]) && is_array($query["tax_query"])
85 ? $query["tax_query"]
86 : [];
87
88 if (isset($tax_query["relation"])) {
89 $existing_relation = strtoupper((string) $tax_query["relation"]);
90 if (in_array($existing_relation, ["AND", "OR"], true)) {
91 $tax_query["relation"] = $existing_relation;
92 } else {
93 unset($tax_query["relation"]);
94 }
95 }
96
97 $tax_query[] = $exclude_clause;
98
99 $query["tax_query"] = $tax_query; // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query
100 return $query;
101 }
102
103 /**
104 * Convert a value into an array of positive term IDs.
105 *
106 * @param mixed $value The raw value.
107 * @return array<int>
108 */
109 private function normalize_term_ids($value): array {
110 if (is_string($value)) {
111 $value = Strings::maybe_mb_split(",", $value);
112 } elseif (is_int($value)) {
113 $value = [$value];
114 } elseif (!is_array($value)) {
115 $value = [];
116 }
117
118 $value = array_map("intval", $value);
119 $value = array_filter($value, function (int $term_id): bool {
120 return 0 < $term_id;
121 });
122
123 return array_values(array_unique($value));
124 }
125 }
126