PluginProbe
BetterLinks – Link Shortener, Link Cloaking, Redirects, Affiliate Link Manager & MCP / trunk
BetterLinks – Link Shortener, Link Cloaking, Redirects, Affiliate Link Manager & MCP vtrunk
3.1.3 3.1.2 3.1.1 3.1.0 3.0.1 3.0.0 2.4.13 2.4.12 2.4.11 2.4.10 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 All 110 releases
betterlinks / includes / API / Terms.php

Terms.php in BetterLinks – Link Shortener, Link Cloaking, Redirects, Affiliate Link Manager & MCP trunk, at includes/API/Terms.php

360 lines 9.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace BetterLinks\API;
4 if ( ! defined( 'ABSPATH' ) ) { exit; }
5
6 use BetterLinks\Traits\ArgumentSchema;
7 use BetterLinks\Helper;
8
9 class Terms extends Controller
10 {
11
12 use \BetterLinks\Traits\Terms;
13 use ArgumentSchema;
14
15 /**
16 * Initialize hooks and option name
17 */
18 public function __construct()
19 {
20 add_action('rest_api_init', array($this, 'register_routes'));
21 }
22
23 /**
24 * Register the routes for the objects of the controller.
25 */
26 public function register_routes()
27 {
28 $endpoint = '/terms/';
29 register_rest_route(
30 $this->namespace,
31 $endpoint,
32 array(
33 array(
34 'methods' => \WP_REST_Server::READABLE,
35 'callback' => array($this, 'get_items'),
36 'permission_callback' => array($this, 'get_items_permissions_check'),
37 'args' => $this->get_terms_schema(),
38 ),
39 )
40 );
41 register_rest_route(
42 $this->namespace,
43 $endpoint . 'tags',
44 array(
45 array(
46 'methods' => \WP_REST_Server::READABLE,
47 'callback' => array($this, 'get_tags'),
48 'permission_callback' => array($this, 'get_items_permissions_check'),
49 'args' => $this->get_terms_schema(),
50 ),
51 )
52 );
53
54 register_rest_route(
55 $this->namespace,
56 $endpoint . 'categories',
57 array(
58 array(
59 'methods' => \WP_REST_Server::READABLE,
60 'callback' => array($this, 'get_categories'),
61 'permission_callback' => array($this, 'get_items_permissions_check'),
62 'args' => $this->get_terms_schema(),
63 ),
64 )
65 );
66
67 register_rest_route(
68 $this->namespace,
69 $endpoint,
70 array(
71 array(
72 'methods' => \WP_REST_Server::CREATABLE,
73 'callback' => array($this, 'create_item'),
74 'permission_callback' => array($this, 'permissions_check'),
75 'args' => $this->get_terms_schema(),
76 ),
77 )
78 );
79
80 register_rest_route(
81 $this->namespace,
82 $endpoint,
83 array(
84 array(
85 'methods' => \WP_REST_Server::EDITABLE,
86 'callback' => array($this, 'update_item'),
87 'permission_callback' => array($this, 'permissions_check'),
88 'args' => $this->get_terms_schema(),
89 ),
90 )
91 );
92
93 register_rest_route(
94 $this->namespace,
95 $endpoint,
96 array(
97 array(
98 'methods' => \WP_REST_Server::DELETABLE,
99 'callback' => array($this, 'delete_item'),
100 'permission_callback' => array($this, 'permissions_check'),
101 'args' => $this->get_terms_schema(),
102 ),
103 )
104 );
105 }
106
107 public function get_tags()
108 {
109 $results = $this->get_all_tags();
110
111 // Force refresh analytics data
112 $analytic = $this->tags_analytic(true);
113
114 return new \WP_REST_Response(
115 array(
116 'success' => true,
117 'data' => array(
118 'results' => $results,
119 'analytic' => $analytic
120 ),
121 ),
122 200
123 );
124 }
125
126 public function get_categories()
127 {
128 $results = $this->get_all_categories();
129
130 // Force refresh analytics data
131 $analytic = $this->categories_analytic(true);
132
133 return new \WP_REST_Response(
134 array(
135 'success' => true,
136 'data' => array(
137 'results' => $results,
138 'analytic' => $analytic
139 ),
140 ),
141 200
142 );
143 }
144 /**
145 * Get betterlinks
146 *
147 * @param WP_REST_Request $request Full data about the request.
148 * @return WP_Error|WP_REST_Request
149 */
150 public function get_items($request)
151 {
152 $query_params = $request->get_query_params();
153 $results = $this->get_all_terms_data($query_params);
154
155 if (count($results) <= 0) {
156 $_term = array(
157 'term_name' => 'Uncategorized',
158 'term_slug' => 'uncategorized',
159 'term_type' => 'category',
160 );
161 $id = Helper::insert_term($_term);
162 if ($id) {
163 $_term['ID'] = $id;
164 $_term['term_order'] = 0;
165 }
166 $results = array($_term);
167 }
168
169 return new \WP_REST_Response(
170 array(
171 'success' => true,
172 'data' => $results,
173 ),
174 200
175 );
176 }
177
178 /**
179 * Create OR Update betterlinks
180 *
181 * @param WP_REST_Request $request Full data about the request.
182 * @return WP_Error|WP_REST_Request
183 */
184 public function create_item($request)
185 {
186 delete_transient(BETTERLINKS_CACHE_LINKS_NAME);
187 $request = $request->get_params();
188
189 $args = array(
190 'ID' => (isset($request['params']['ID']) ? absint(sanitize_text_field($request['params']['ID'])) : 0),
191 'term_name' => (isset($request['params']['term_name']) ? sanitize_text_field($request['params']['term_name']) : ''),
192 'term_slug' => (isset($request['params']['term_slug']) ? sanitize_text_field($request['params']['term_slug']) : ''),
193 'term_type' => (isset($request['params']['term_type']) ? sanitize_text_field($request['params']['term_type']) : ''),
194 );
195 $is_update = \BetterLinks\Helper::is_term_exists($args['ID'], $args['term_type']);
196
197 if (empty($args['term_slug'])) return;
198
199 if ($is_update) {
200 if ($args['term_type'] === 'category') {
201 // For categories, convert to the format expected by update_term
202 $category_args = array(
203 'cat_id' => $args['ID'],
204 'cat_name' => $args['term_name'],
205 'cat_slug' => $args['term_slug'],
206 );
207 $results = $this->update_term($category_args);
208 } else {
209 // For tags, use the existing update_tag method
210 $results = $this->update_tag($args);
211 }
212 return new \WP_REST_Response(
213 array(
214 'success' => true,
215 'update' => true,
216 'data' => $results,
217 ),
218 200
219 );
220 }
221 $results = $this->create_term($args);
222 return new \WP_REST_Response(
223 array(
224 'success' => true,
225 'data' => $results,
226 ),
227 200
228 );
229 }
230
231 /**
232 * Create OR Update betterlinks
233 *
234 * @param WP_REST_Request $request Full data about the request.
235 * @return WP_Error|WP_REST_Request
236 */
237 public function update_item($request)
238 {
239 delete_transient(BETTERLINKS_CACHE_LINKS_NAME);
240 $request = $request->get_params();
241 $args = array(
242 'cat_id' => (isset($request['params']['ID']) ? absint(sanitize_text_field($request['params']['ID'])) : 0),
243 'cat_name' => (isset($request['params']['term_name']) ? sanitize_text_field($request['params']['term_name']) : ''),
244 'cat_slug' => (isset($request['params']['term_slug']) ? sanitize_text_field($request['params']['term_slug']) : ''),
245 );
246
247 // Protected categories (e.g. "Uncategorized", "Link in Bio") cannot be renamed.
248 $protected = array_map('intval', (array) apply_filters('betterlinks/protected_term_ids', array(1)));
249 if ($args['cat_id'] && in_array((int) $args['cat_id'], $protected, true)) {
250 return new \WP_REST_Response(
251 array(
252 'success' => false,
253 'data' => array(
254 'message' => __('This category is protected and cannot be edited.', 'betterlinks'),
255 'term_id' => $args['cat_id'],
256 ),
257 ),
258 403
259 );
260 }
261
262 $this->update_term($args);
263
264 // `success` must report the outcome of the rename. This used to be
265 // is_bool($request['params']['ID']) — ID is an integer, so every successful
266 // rename answered success:false and clients showed a failure toast.
267 return new \WP_REST_Response(
268 array(
269 'success' => true,
270 'update' => true,
271 'data' => $request['params'],
272 ),
273 200
274 );
275 }
276
277 /**
278 * Delete betterlinks
279 *
280 * @param WP_REST_Request $request Full data about the request.
281 * @return WP_Error|WP_REST_Request
282 */
283 public function delete_item($request)
284 {
285 delete_transient(BETTERLINKS_CACHE_LINKS_NAME);
286 $request = $request->get_params();
287
288 // Check if trying to delete the default 'Uncategorized' category (ID: 1)
289 // This can come as either cat_id or tag_id parameter
290 $term_id_to_delete = null;
291 if (isset($request['cat_id'])) {
292 $term_id_to_delete = $request['cat_id'];
293 } elseif (isset($request['tag_id'])) {
294 $term_id_to_delete = $request['tag_id'];
295 }
296
297 // No term id means nothing can be deleted. Answering 200/success:true here let a
298 // client that sent an undefined id show "Deleted" toasts while the row stayed put,
299 // which is how a stale admin bundle looked like a broken delete feature.
300 if (!$term_id_to_delete) {
301 return new \WP_REST_Response(
302 array(
303 'success' => false,
304 'data' => array(
305 'message' => __('No category or tag ID was supplied.', 'betterlinks'),
306 ),
307 ),
308 400
309 );
310 }
311
312 $protected = array_map('intval', (array) apply_filters('betterlinks/protected_term_ids', array(1)));
313 if ($term_id_to_delete && in_array((int) $term_id_to_delete, $protected, true)) {
314 return new \WP_REST_Response(
315 array(
316 'success' => false,
317 'data' => array(
318 'message' => __('This category is protected and cannot be deleted.', 'betterlinks'),
319 'term_id' => $term_id_to_delete,
320 ),
321 ),
322 403 // Forbidden status code
323 );
324 }
325
326 $this->delete_term($request);
327 return new \WP_REST_Response(
328 array(
329 'success' => true,
330 'data' => array(
331 'cat_id' => $term_id_to_delete,
332 ),
333 ),
334 200
335 );
336 }
337
338 /**
339 * Check if a given request has access to update a setting
340 *
341 * @param WP_REST_Request $request Full data about the request.
342 * @return WP_Error|bool
343 */
344 public function get_items_permissions_check($request)
345 {
346 return apply_filters('betterlinks/api/terms_get_items_permissions_check', current_user_can('manage_options'));
347 }
348
349 /**
350 * Check if a given request has access to update a setting
351 *
352 * @param WP_REST_Request $request Full data about the request.
353 * @return WP_Error|bool
354 */
355 public function permissions_check($request)
356 {
357 return apply_filters('betterlinks/api/terms_manage_permissions_check', current_user_can('manage_options'));
358 }
359 }
360