PluginProbe
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot / 4.9.2
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot v4.9.2
4.9.2 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 All 200 releases
betterdocs / includes / Abilities / Terms / DeleteTerm.php

DeleteTerm.php in BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot 4.9.2, at includes/Abilities/Terms/DeleteTerm.php

165 lines 4.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Delete a doc category or doc tag ability.
4 *
5 * @package BetterDocs
6 * @since 4.9.0
7 */
8
9 namespace WPDeveloper\BetterDocs\Abilities\Terms;
10
11 if ( ! defined( 'ABSPATH' ) ) {
12 exit; // Exit if accessed directly.
13 }
14
15 use WPDeveloper\BetterDocs\Abilities\AbilityBase;
16 use WPDeveloper\BetterDocs\Abilities\Traits\ResolvesTerms;
17 use WPDeveloper\BetterDocs\Abilities\Traits\ShapesTerms;
18
19 /**
20 * Delete a doc category or doc tag.
21 *
22 * There is no trash for terms — WordPress deletes them outright, which is why
23 * `wp/v2` requires `force=true` and why this tool is annotated destructive with
24 * no gentler mode to fall back on.
25 *
26 * **The docs survive.** Deleting a category unfiles every doc in it; it does not
27 * delete them. Deleting a parent category promotes its children to the top
28 * level rather than removing them. Both are WordPress' behaviour and both are in
29 * the tool description, because "delete the empty category" is a request an
30 * agent will act on without checking whether it is really empty.
31 *
32 * @since 4.9.0
33 */
34 class DeleteTerm extends AbilityBase {
35
36 use ResolvesTerms;
37 use ShapesTerms;
38
39 /**
40 * @since 4.9.0
41 */
42 public function __construct() {
43 $this->id = 'betterdocs/delete-term';
44 $this->label = __( 'Delete term', 'betterdocs' );
45 $this->description = __( 'Delete a BetterDocs doc category or doc tag. Terms have no trash, so this cannot be undone. Docs in a deleted category are not deleted — they become uncategorised — and child categories move up to the top level.', 'betterdocs' );
46 $this->capability = 'delete_doc_terms';
47 }
48
49 /**
50 * @since 4.9.0
51 *
52 * @return array
53 */
54 public function get_annotations() {
55 return [
56 'readonly' => false,
57 'destructive' => true,
58 'idempotent' => false,
59 'priority' => 3.0,
60 'openWorldHint' => false
61 ];
62 }
63
64 /**
65 * @since 4.9.0
66 *
67 * @return array
68 */
69 public function get_input_schema() {
70 return [
71 'type' => 'object',
72 'additionalProperties' => false,
73 'required' => [ 'taxonomy', 'id' ],
74 'properties' => [
75 'taxonomy' => self::taxonomy_schema(),
76 'id' => [
77 'type' => 'integer',
78 'description' => __( 'The term id to delete. Required.', 'betterdocs' )
79 ]
80 ],
81 'default' => []
82 ];
83 }
84
85 /**
86 * @since 4.9.0
87 *
88 * @return array
89 */
90 public function get_output_schema() {
91 return [
92 'type' => 'object',
93 'properties' => [
94 'id' => [ 'type' => 'integer' ],
95 'taxonomy' => [ 'type' => 'string' ],
96 'deleted' => [ 'type' => 'boolean' ],
97 'name' => [ 'type' => 'string' ],
98 // Published docs only — WordPress' term counts ignore drafts.
99 'docs' => [ 'type' => 'integer' ]
100 ]
101 ];
102 }
103
104 /**
105 * @since 4.9.0
106 *
107 * @param array $input Validated input.
108 * @return array|\WP_Error
109 */
110 public function execute( $input ) {
111 $taxonomy = isset( $input['taxonomy'] ) ? (string) $input['taxonomy'] : '';
112
113 // Before anything is read or written: a taxonomy that is switched off
114 // answers with the setting to change, not with `not_found` (ADR-061).
115 $available = $this->taxonomy_available( $taxonomy );
116
117 if ( is_wp_error( $available ) ) {
118 return $available;
119 }
120
121 $term = $this->require_term( isset( $input['id'] ) ? $input['id'] : 0, $taxonomy );
122
123 if ( is_wp_error( $term ) ) {
124 return $term;
125 }
126
127 $name = (string) $term->name;
128 $count = (int) $term->count;
129
130 // `force` is not optional for a taxonomy term: `WP_REST_Terms_Controller`
131 // refuses without it, because there is nowhere to trash a term to.
132 $deleted = $this->dispatch(
133 'DELETE',
134 '/' . $taxonomy . '/' . (int) $term->term_id,
135 [ 'force' => true ],
136 'wp/v2'
137 );
138
139 if ( is_wp_error( $deleted ) ) {
140 return $this->map_term_error(
141 $deleted,
142 $taxonomy,
143 sprintf(
144 /* translators: 1: term type, 2: term id. */
145 __( 'delete %1$s #%2$d', 'betterdocs' ),
146 $this->term_object_name( $taxonomy ),
147 (int) $term->term_id
148 )
149 );
150 }
151
152 return [
153 'id' => (int) $term->term_id,
154 'taxonomy' => $taxonomy,
155 'deleted' => true,
156 'name' => $name,
157 // How many docs just lost this term. Reported because an agent that
158 // deleted a category holding forty docs should be able to say so.
159 // WordPress counts published posts only, so drafts in the category
160 // are unfiled without being counted here.
161 'docs' => $count
162 ];
163 }
164 }
165