PluginProbe
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot / 4.9.0
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot v4.9.0
4.9.1 4.9.0 4.8.2 4.8.1 4.8.0 4.7.0 4.6.2 4.6.1 4.6.0 4.5.6 4.5.5 4.5.4 4.5.3 4.5.2 4.5.1 4.5.0 4.4.1 4.4.0 3.3.4 3.4.0 3.4.1 3.4.2 3.5.0 3.5.1 3.5.2 All 199 releases
betterdocs / includes / Abilities / Faq / DeleteFAQGroup.php

DeleteFAQGroup.php in BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot 4.9.0, at includes/Abilities/Faq/DeleteFAQGroup.php

190 lines 5.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Delete an FAQ group ability.
4 *
5 * @package BetterDocs
6 * @since 4.9.0
7 */
8
9 namespace WPDeveloper\BetterDocs\Abilities\Faq;
10
11 if ( ! defined( 'ABSPATH' ) ) {
12 exit; // Exit if accessed directly.
13 }
14
15 use WPDeveloper\BetterDocs\Abilities\AbilityBase;
16 use WPDeveloper\BetterDocs\Abilities\AbilityError;
17 use WPDeveloper\BetterDocs\Abilities\Traits\ShapesFAQs;
18
19 /**
20 * Delete an FAQ group, and optionally everything in it.
21 *
22 * With `with_all_faqs` false — the default — the group goes and its questions
23 * survive as uncategorised FAQs, findable again with
24 * `bd-list-faqs {group_id: 0}`… which does not exist, so say it plainly: they
25 * stay in the site and `bd-list-faqs` with no group still finds them.
26 *
27 * With `with_all_faqs` true every FAQ in the group is **permanently deleted**,
28 * drafts and trashed ones included — `Helper::delete_specific_faq_posts_by_faq_category()`
29 * force-deletes across every status. There is no undo, which is why the flag
30 * defaults to false and the tool is annotated destructive.
31 *
32 * @since 4.9.0
33 */
34 class DeleteFAQGroup extends AbilityBase {
35
36 use ShapesFAQs;
37
38 /**
39 * @since 4.9.0
40 */
41 public function __construct() {
42 $this->id = 'betterdocs/delete-faq-group';
43 $this->label = __( 'Delete FAQ group', 'betterdocs' );
44 $this->description = __( 'Delete a BetterDocs FAQ group. By default its questions survive without a group; with with_all_faqs true every FAQ in the group is permanently deleted, including drafts. Docs that referenced the group stop showing it.', 'betterdocs' );
45 $this->capability = 'edit_others_docs';
46 }
47
48 /**
49 * @since 4.9.0
50 *
51 * @return array
52 */
53 public function get_annotations() {
54 return [
55 'readonly' => false,
56 'destructive' => true,
57 'idempotent' => false,
58 'priority' => 2.5,
59 'openWorldHint' => false
60 ];
61 }
62
63 /**
64 * @since 4.9.0
65 *
66 * @return array
67 */
68 public function get_input_schema() {
69 return [
70 'type' => 'object',
71 'additionalProperties' => false,
72 'required' => [ 'id' ],
73 'properties' => [
74 'id' => [
75 'type' => 'integer',
76 'description' => __( 'The FAQ group id. Required.', 'betterdocs' )
77 ],
78 'with_all_faqs' => [
79 'type' => 'boolean',
80 'default' => false,
81 'description' => __( 'true also deletes every FAQ in the group, permanently and in every status. false (the default) leaves the questions in place without a group.', 'betterdocs' )
82 ]
83 ],
84 'default' => []
85 ];
86 }
87
88 /**
89 * @since 4.9.0
90 *
91 * @return array
92 */
93 public function get_output_schema() {
94 return [
95 'type' => 'object',
96 'properties' => [
97 'id' => [ 'type' => 'integer' ],
98 'deleted' => [ 'type' => 'boolean' ],
99 'faqs_deleted' => [ 'type' => 'boolean' ],
100 'name' => [ 'type' => 'string' ],
101 'faqs' => [ 'type' => 'integer' ]
102 ]
103 ];
104 }
105
106 /**
107 * @since 4.9.0
108 *
109 * @param array $input Validated input.
110 * @return array|\WP_Error
111 */
112 public function execute( $input ) {
113 $id = isset( $input['id'] ) ? (int) $input['id'] : 0;
114 $term = $id > 0 ? get_term( $id, self::GROUP_TAXONOMY ) : null;
115
116 if ( ! $term || is_wp_error( $term ) ) {
117 return AbilityError::not_found( 'FAQ group', $id );
118 }
119
120 $with_all = ! empty( $input['with_all_faqs'] );
121
122 // Reported from before the delete: afterwards the term is gone and the
123 // count with it, and an agent that just removed something should be able
124 // to say what it removed.
125 $name = (string) $term->name;
126 $faqs = $this->count_faqs_in_group( $id );
127
128 $result = $this->dispatch(
129 'POST',
130 '/faq/delete_category',
131 [
132 'term_id' => $id,
133 'with_all_post' => $with_all
134 ],
135 self::FAQ_NS
136 );
137
138 if ( is_wp_error( $result ) ) {
139 return $this->map_faq_error( $result, __( 'delete an FAQ group', 'betterdocs' ) );
140 }
141
142 if ( true !== $result ) {
143 return AbilityError::upstream( __( 'BetterDocs did not confirm the FAQ group deletion.', 'betterdocs' ) );
144 }
145
146 return [
147 'id' => $id,
148 'deleted' => true,
149 'faqs_deleted' => $with_all,
150 'name' => $name,
151 'faqs' => $faqs
152 ];
153 }
154
155 /**
156 * How many FAQs the group holds, in any status.
157 *
158 * The term's own `count` tracks published posts only, and "5 questions were
159 * deleted" has to include the drafts that went with them.
160 *
161 * @since 4.9.0
162 *
163 * @param int $id Group id.
164 * @return int
165 */
166 protected function count_faqs_in_group( $id ) {
167 $query = new \WP_Query(
168 [
169 'post_type' => self::FAQ_POST_TYPE,
170 'post_status' => [ 'publish', 'draft', 'pending', 'future', 'private', 'trash' ],
171 'posts_per_page' => 1,
172 'fields' => 'ids',
173 'no_found_rows' => false,
174 'update_post_meta_cache' => false,
175 'update_post_term_cache' => false,
176 // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query -- counting one group's FAQs is the question being asked.
177 'tax_query' => [
178 [
179 'taxonomy' => self::GROUP_TAXONOMY,
180 'field' => 'term_id',
181 'terms' => (int) $id
182 ]
183 ]
184 ]
185 );
186
187 return (int) $query->found_posts;
188 }
189 }
190