PluginProbe
Tag, Category, and Taxonomy Manager – Autotagger Automatically Add Terms / 3.51.0
Tag, Category, and Taxonomy Manager – Autotagger Automatically Add Terms v3.51.0
3.54.0 3.53.0 3.52.0 3.51.0 3.50.0 3.45.0 3.38.0 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.4.5 3.40.0 3.40.1 3.41.0 3.42.0 3.43.0 3.44.0 3.5.0 3.5.1 3.5.2 3.5.3 3.6.0 3.6.1 All 178 releases
simple-tags / inc / terms-functions.php

terms-functions.php in Tag, Category, and Taxonomy Manager – Autotagger Automatically Add Terms 3.51.0, at inc/terms-functions.php

283 lines 9.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Generate a unique term slug should user decide to copy same term more than once.
5 *
6 * @param string $slug The initial slug to check
7 * @param string $taxonomy The taxonomy to check against
8 * @return string Unique slug
9 */
10 function taxopress_get_unique_term_slug($slug, $taxonomy)
11 {
12 $original_slug = $slug;
13 $count = 1;
14
15 while (term_exists($slug, $taxonomy)) {
16 $slug = $original_slug . '-' . $count;
17 $count++;
18 }
19
20 return $slug;
21 }
22
23 /**
24 * Fetch post IDs for Terms screen bulk/row actions without hydrating WP_Post objects.
25 *
26 * @param array $args Optional WP_Query arguments.
27 * @return int[]
28 */
29 function taxopress_get_post_ids_for_terms_action($args = [])
30 {
31 $defaults = [
32 'post_type' => 'any',
33 'posts_per_page' => -1,
34 'fields' => 'ids',
35 'no_found_rows' => true,
36 'update_post_meta_cache' => false,
37 'update_post_term_cache' => false,
38 ];
39
40 $post_ids = get_posts(array_merge($defaults, $args));
41
42 if (empty($post_ids)) {
43 return [];
44 }
45
46 return array_map('intval', $post_ids);
47 }
48
49 /**
50 * Preserve the current Terms screen filters when row actions redirect/reload.
51 *
52 * @param array $extra Extra query arguments.
53 * @return array
54 */
55 function taxopress_get_terms_screen_query_args($extra = [])
56 {
57 $preserve_keys = [
58 'terms_filter_post_type',
59 'terms_filter_taxonomy',
60 'taxonomy_type',
61 'taxopress_terms_taxonomy',
62 'taxopress_show_all',
63 'orderby',
64 'order',
65 'paged',
66 's',
67 ];
68
69 $query_args = ['page' => 'st_terms'];
70
71 foreach ($preserve_keys as $key) {
72 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Preserving current non-state-changing table filters.
73 if (isset($_REQUEST[$key]) && $_REQUEST[$key] !== '') {
74 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Preserving current non-state-changing table filters.
75 $query_args[$key] = sanitize_text_field(wp_unslash($_REQUEST[$key]));
76 }
77 }
78
79 return array_merge($query_args, $extra);
80 }
81
82 /**
83 * Keep a copied term near the original in saved manual order when that order exists.
84 *
85 * @param string $taxonomy Taxonomy slug.
86 * @param int $original_term_id Original term ID.
87 * @param int $copied_term_id Copied term ID.
88 */
89 function taxopress_place_copied_term_near_original($taxonomy, $original_term_id, $copied_term_id)
90 {
91 $taxonomy = sanitize_key($taxonomy);
92 $original_term_id = (int) $original_term_id;
93 $copied_term_id = (int) $copied_term_id;
94
95 if (empty($taxonomy) || $original_term_id <= 0 || $copied_term_id <= 0) {
96 return;
97 }
98
99 $option_name = 'taxopress_term_order_' . $taxonomy;
100 $custom_order = array_values(array_filter(array_map('intval', (array) get_option($option_name, []))));
101
102 if (empty($custom_order)) {
103 return;
104 }
105
106 $custom_order = array_values(array_diff($custom_order, [$copied_term_id]));
107 $original_position = array_search($original_term_id, $custom_order, true);
108
109 if ($original_position === false) {
110 $custom_order[] = $copied_term_id;
111 } else {
112 $taxonomy_settings = taxopress_get_all_edited_taxonomy_data();
113 $order_setting = isset($taxonomy_settings[$taxonomy]['order']) ? strtolower($taxonomy_settings[$taxonomy]['order']) : 'asc';
114 $insert_position = ($order_setting === 'desc') ? $original_position + 1 : $original_position;
115 array_splice($custom_order, $insert_position, 0, [$copied_term_id]);
116 }
117
118 update_option($option_name, array_values(array_unique($custom_order)));
119 }
120
121 /**
122 * Handle the save and deletion of terms data.
123 */
124 function taxopress_process_terms()
125 {
126
127 if (wp_doing_ajax()) {
128 return;
129 }
130
131 if (!is_admin()) {
132 return;
133 }
134
135 if (!current_user_can('simple_tags')) {
136 return;
137 }
138
139 if (empty($_GET)) {
140 return;
141 }
142
143 if (!isset($_GET['page'])) {
144 return;
145 }
146 if ('st_terms' !== $_GET['page']) {
147 return;
148 }
149
150 if (isset($_REQUEST['action']) && $_REQUEST['action'] === 'taxopress-delete-terms') {
151 $nonce = !empty($_REQUEST['_wpnonce']) ? sanitize_text_field($_REQUEST['_wpnonce']) : '';
152 if (wp_verify_nonce($nonce, 'terms-action-request-nonce') && isset($_REQUEST['taxopress_terms'])) {
153 $term = get_term(sanitize_text_field($_REQUEST['taxopress_terms']));
154 wp_delete_term($term->term_id, $term->taxonomy);
155 }
156 add_action('admin_notices', "taxopress_term_delete_success_admin_notice");
157 add_filter('removable_query_args', 'taxopress_delete_terms_filter_removable_query_args');
158 }
159
160 if (isset($_REQUEST['action']) && $_REQUEST['action'] === 'taxopress-remove-from-posts') {
161 $nonce = !empty($_REQUEST['_wpnonce']) ? sanitize_text_field($_REQUEST['_wpnonce']) : '';
162 if (wp_verify_nonce($nonce, 'terms-action-request-nonce') && isset($_REQUEST['taxopress_terms'])) {
163 $term = get_term(sanitize_text_field($_REQUEST['taxopress_terms']));
164 $args = array(
165 'post_type' => 'any',
166 'posts_per_page' => -1,
167 // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query -- Necessary to filter posts by specific term for accurate removal
168 'tax_query' => array(
169 array(
170 'taxonomy' => $term->taxonomy,
171 'field' => 'id',
172 'terms' => $term->term_id
173 )
174 )
175 );
176 $post_ids = taxopress_get_post_ids_for_terms_action($args);
177 $counter = 0;
178 foreach ($post_ids as $post_id) {
179 $remove = wp_remove_object_terms($post_id, $term->term_id, $term->taxonomy);
180 if ($remove) {
181 clean_object_term_cache($post_id, $term->taxonomy);
182 clean_term_cache($term->term_id, $term->taxonomy);
183 $counter++;
184 }
185 }
186 }
187 add_action('admin_notices', "taxopress_term_posts_remov_success_admin_notice");
188 add_filter('removable_query_args', 'taxopress_delete_terms_filter_removable_query_args');
189 }
190
191 if (isset($_REQUEST['action']) && $_REQUEST['action'] === 'taxopress-copy-term') {
192 $nonce = !empty($_REQUEST['_wpnonce']) ? sanitize_text_field($_REQUEST['_wpnonce']) : '';
193 if (wp_verify_nonce($nonce, 'terms-action-request-nonce') && isset($_REQUEST['taxopress_terms'])) {
194 $term = get_term(sanitize_text_field($_REQUEST['taxopress_terms']));
195
196 $taxopress_term_name = $term->name . ' Copy';
197 $base_slug = $term->slug . '-copy';
198 $taxopress_term_slug = taxopress_get_unique_term_slug($base_slug, $term->taxonomy);
199 $taxopress_term_data = wp_insert_term($taxopress_term_name, $term->taxonomy, [
200 'slug' => $taxopress_term_slug,
201 'description' => $term->description,
202 'parent' => $term->parent,
203 ]);
204
205 if (!is_wp_error($taxopress_term_data)) {
206 $taxopress_term_id = $taxopress_term_data['term_id'];
207 taxopress_place_copied_term_near_original($term->taxonomy, $term->term_id, $taxopress_term_id);
208 $_REQUEST['taxopress_copied_term_id'] = $taxopress_term_id;
209 $_REQUEST['taxopress_original_term_id'] = $term->term_id;
210 $_REQUEST['taxopress_copied_taxonomy'] = $term->taxonomy;
211
212 $args = array(
213 'post_type' => 'any',
214 'posts_per_page' => -1,
215 // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query -- Necessary to filter posts by specific term for accurate term copying
216 'tax_query' => array(
217 array(
218 'taxonomy' => $term->taxonomy,
219 'field' => 'id',
220 'terms' => $term->term_id
221 )
222 )
223 );
224 $post_ids = taxopress_get_post_ids_for_terms_action($args);
225
226 foreach ($post_ids as $post_id) {
227 wp_set_object_terms($post_id, $taxopress_term_id, $term->taxonomy, true);
228 }
229 }
230 }
231 add_action('admin_notices', "taxopress_term_copy_success_admin_notice");
232 add_filter('removable_query_args', 'taxopress_delete_terms_filter_removable_query_args');
233 }
234 }
235 add_action('admin_init', 'taxopress_process_terms', 8);
236
237 /**
238 * Successful term copy callback.
239 */
240 function taxopress_term_copy_success_admin_notice()
241 {
242 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
243 echo taxopress_admin_notices_helper(esc_html__('Term copied successfully.', 'simple-tags'), true);
244 }
245
246 /**
247 * Successful deleted callback.
248 */
249 function taxopress_term_delete_success_admin_notice()
250 {
251 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
252 echo taxopress_admin_notices_helper(esc_html__('Term deleted successfully.', 'simple-tags'), false);
253 }
254
255 /**
256 * Successful remove term from posts callback.
257 */
258 function taxopress_term_posts_remov_success_admin_notice()
259 {
260 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
261 echo taxopress_admin_notices_helper(esc_html__('Term removed from all posts successfully.', 'simple-tags'), true);
262 }
263
264 /**
265 * Filters the list of query arguments which get removed from admin area URLs in WordPress.
266 *
267 * @link https://core.trac.wordpress.org/ticket/23367
268 *
269 * @param string[] $args Array of removable query arguments.
270 * @return string[] Updated array of removable query arguments.
271 */
272 function taxopress_delete_terms_filter_removable_query_args(array $args)
273 {
274 return array_merge($args, [
275 'action',
276 'taxopress_terms',
277 '_wpnonce',
278 'taxopress_copied_term_id',
279 'taxopress_original_term_id',
280 'taxopress_copied_taxonomy',
281 ]);
282 }
283