PluginProbe
Tag, Category, and Taxonomy Manager – Autotagger Automatically Add Terms / 3.50.0
Tag, Category, and Taxonomy Manager – Autotagger Automatically Add Terms v3.50.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 / class.admin.mass.php

class.admin.mass.php in Tag, Category, and Taxonomy Manager – Autotagger Automatically Add Terms 3.50.0, at inc/class.admin.mass.php

535 lines 20.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 class SimpleTags_Admin_Mass
4 {
5 public const MENU_SLUG = 'st_options';
6
7 /**
8 * SimpleTags_Admin_Mass constructor.
9 */
10 public function __construct()
11 {
12 // Ajax action, JS Helper and admin action
13 add_action('admin_init', array( __CLASS__, 'admin_init' ));
14
15 // Admin menu
16 add_action('admin_menu', array( __CLASS__, 'admin_menu' ));
17
18 // Register taxo, parent method...
19 SimpleTags_Admin::register_taxonomy();
20 }
21
22 /**
23 * Add WP admin menu for Tags
24 *
25 * @return void
26 * @author WebFactory Ltd
27 */
28 public static function admin_menu()
29 {
30 add_submenu_page(
31 self::MENU_SLUG,
32 esc_html__('Mass Edit Terms', 'simple-tags'),
33 esc_html__('Mass Edit Terms', 'simple-tags'),
34 'simple_tags',
35 'st_mass_terms',
36 array(
37 __CLASS__,
38 'pageMassEditTags',
39 )
40 );
41 }
42
43 /**
44 * Control POST data for mass edit tags
45 *
46 */
47 public static function admin_init()
48 {
49 if (! current_user_can('simple_tags')) {
50 return false;
51 }
52
53 // Get GET data
54 if (isset($_GET['post_type'])) {
55 $type = stripslashes(sanitize_text_field($_GET['post_type']));
56 }
57
58 if (isset($_POST['update_mass'])) {
59 // origination and intention
60 if (! (wp_verify_nonce(sanitize_text_field($_POST['secure_mass']), 'st_mass_terms'))) {
61 add_settings_error(__CLASS__, __CLASS__, esc_html__('Security problem. Try again.', 'simple-tags'), 'error taxopress-notice');
62
63 return false;
64 }
65
66 if (isset($_POST['tags'])) {
67 $counter = 0;
68 foreach ((array) array_map('sanitize_text_field', $_POST['tags']) as $object_id => $tag_list) {
69 // Trim data
70 $tag_list = trim(stripslashes($tag_list));
71
72 // String to array
73 $tags = explode(',', $tag_list);
74
75 // Remove empty and trim tag
76 $tags = array_filter($tags, '_delete_empty_element');
77
78 $show_slug = SimpleTags_Plugin::get_option_value('enable_mass-edit_terms_slug');
79
80 $term_ids = array();
81 foreach ($tags as $tag) {
82 $tag = trim($tag);
83 if (empty($tag)) {
84 continue;
85 }
86
87 if ($show_slug && preg_match('/^(.+?)\s*\(([^)]+)\)$/', $tag, $matches)) {
88 $term_name = trim($matches[1]);
89 $term_slug = trim($matches[2]);
90
91 $term = get_term_by('slug', $term_slug, SimpleTags_Admin::$taxonomy);
92
93 if ($term) {
94 if ($term->name === $term_name) {
95 $term_ids[] = $term->term_id;
96 } else {
97 $unique_slug = $term_slug;
98 $counter = 1;
99 while (get_term_by('slug', $unique_slug, SimpleTags_Admin::$taxonomy)) {
100 $unique_slug = $term_slug . '-' . $counter;
101 $counter++;
102 }
103 $new_term = wp_insert_term($term_name, SimpleTags_Admin::$taxonomy, array('slug' => $unique_slug));
104 if (!is_wp_error($new_term)) {
105 $term_ids[] = $new_term['term_id'];
106 }
107 }
108 } else {
109 $new_term = wp_insert_term($term_name, SimpleTags_Admin::$taxonomy, array('slug' => $term_slug));
110 if (!is_wp_error($new_term)) {
111 $term_ids[] = $new_term['term_id'];
112 }
113 }
114 } else {
115 if ($show_slug) {
116 $tag = trim(preg_replace('/\s*\([^)]+\)$/', '', $tag));
117 }
118
119 $term = get_term_by('name', $tag, SimpleTags_Admin::$taxonomy);
120 if ($term) {
121 $term_ids[] = $term->term_id;
122 } else {
123 $new_term = wp_insert_term($tag, SimpleTags_Admin::$taxonomy);
124 if (!is_wp_error($new_term)) {
125 $term_ids[] = $new_term['term_id'];
126 }
127 }
128 }
129 }
130
131 wp_set_object_terms($object_id, $term_ids, SimpleTags_Admin::$taxonomy);
132 $counter++;
133
134 // Clean cache
135 clean_post_cache($object_id);
136 }
137
138 add_settings_error(__CLASS__, __CLASS__, sprintf(esc_html__('%1$s %2$s(s) terms updated with success !', 'simple-tags'), (int) $counter, strtolower(SimpleTags_Admin::$post_type_name)), 'updated taxopress-notice');
139
140 return true;
141 }
142 }
143
144 return false;
145 }
146
147 /**
148 * Helper function to extract term name (ignoring slug in brackets)
149 */
150 private static function extractTermName($term)
151 {
152 return trim(preg_replace('/\s*\(.*?\)$/', '', $term));
153 }
154
155 /**
156 * WP Page - Mass edit tags
157 *
158 */
159 public static function pageMassEditTags()
160 {
161 global $wpdb, $wp_locale, $wp_query;
162 list($post_stati, $avail_post_stati) = self::edit_data_query();
163
164 if (! isset($_GET['paged'])) {
165 $_GET['paged'] = 1;
166 }
167
168 // Display message
169 settings_errors(__CLASS__);
170 ?>
171 <div class="taxopress-block-wrap">
172 <div class="wrap st_wrap tagcloudui st_mass_terms-page admin-settings">
173 <form id="posts-filter" action="" method="get">
174 <input type="hidden" name="page" value="st_mass_terms"/>
175 <input type="hidden" name="taxo" value="<?php echo esc_attr(SimpleTags_Admin::$taxonomy); ?>"/>
176 <input type="hidden" name="cpt" value="<?php echo esc_attr(SimpleTags_Admin::$post_type); ?>"/>
177
178 <h1><?php _e('Mass Edit Terms', 'simple-tags'); ?></h1>
179 <br>
180 <div class="taxopress-description"><?php esc_html_e('This feature allows users to quickly add or remove terms from multiple posts.', 'simple-tags'); ?></div>
181 <br>
182
183 <ul class="subsubsub">
184 <?php
185 $status_links = array();
186 $num_posts = wp_count_posts(SimpleTags_Admin::$post_type, 'readable');
187 $class = (empty($_GET['post_status']) && empty($_GET['post_type'])) ? ' class="current"' : '';
188 $status_links[] = '<li><a href="' . admin_url('admin.php') . '?page=st_mass_terms&amp;cpt=' . SimpleTags_Admin::$post_type . '&amp;taxo=' . SimpleTags_Admin::$taxonomy . '"' . $class . '>' . esc_html__('All', 'simple-tags') . '</a>';
189 foreach ($post_stati as $status => $label) {
190 $class = '';
191
192 if (! in_array($status, $avail_post_stati)) {
193 continue;
194 }
195
196 if (empty($num_posts->$status)) {
197 continue;
198 }
199 if (isset($_GET['post_status']) && $status == $_GET['post_status']) {
200 $class = ' class="current"';
201 }
202
203 $status_links[] = '<li><a href="' . admin_url('admin.php') . '?page=st_mass_terms&amp;cpt=' . SimpleTags_Admin::$post_type . '&amp;taxo=' . SimpleTags_Admin::$taxonomy . '&amp;post_status=' . $status . '"' . $class . '>' . sprintf(_n($label[2][0], $label[2][1], (int) $num_posts->$status), number_format_i18n($num_posts->$status)) . '</a>';
204 }
205 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
206 echo implode(' |</li>', $status_links) . '</li>';
207 unset($status_links);
208
209 $class = (! empty($_GET['post_type'])) ? ' class="current"' : '';
210 ?>
211 </ul>
212
213 <?php if (isset($_GET['post_status'])) : ?>
214 <input type="hidden" name="post_status" value="<?php echo esc_attr(sanitize_text_field($_GET['post_status'])) ?>"/>
215 <?php endif; ?>
216
217
218 <p class="search-box">
219 <input type="text" id="post-search-input" placeholder="<?php esc_attr_e('Search post title and content', 'simple-tags'); ?>" name="s" value="<?php the_search_query(); ?>"/>
220 <input type="submit" value="<?php _e('Search', 'simple-tags'); ?>" class="button"/>
221 </p>
222
223 <div class="tablenav custom-nav">
224 <?php
225 $posts_per_page = (isset($_GET['posts_per_page'])) ? (int) $_GET['posts_per_page'] : 0;
226 if ((int) $posts_per_page == 0) {
227 $posts_per_page = 15;
228 }
229
230 $page_links = paginate_links(array(
231 'base' => add_query_arg('paged', '%#%'),
232 'format' => '',
233 'total' => ceil($wp_query->found_posts / $posts_per_page),
234 'current' => ((int) $_GET['paged'])
235 ));
236
237 if ($page_links) {
238 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
239 echo "<div class='tablenav-pages'>". $page_links ."</div>";
240 }
241 ?>
242
243 <div style="float: left">
244 <?php
245 if (! is_singular()) {
246 $arc_result = $wpdb->get_results($wpdb->prepare("SELECT DISTINCT YEAR(post_date) AS yyear, MONTH(post_date) AS mmonth FROM $wpdb->posts WHERE post_type = %s ORDER BY post_date DESC", SimpleTags_Admin::$post_type));
247
248 $month_count = count($arc_result);
249
250 if (! isset($_GET['m'])) {
251 $_GET['m'] = '';
252 }
253
254 if ($month_count && ! (1 == $month_count && 0 == $arc_result[0]->mmonth)) {
255 ?>
256 <select name='m'>
257 <option <?php selected(@sanitize_text_field($_GET['m']), 0); ?>
258 value='0'><?php _e('Show all dates', 'simple-tags'); ?></option>
259 <?php
260 foreach ($arc_result as $arc_row) {
261 if ($arc_row->yyear == 0) {
262 continue;
263 }
264 $arc_row->mmonth = zeroise($arc_row->mmonth, 2);
265
266 if ($arc_row->yyear . $arc_row->mmonth == $_GET['m']) {
267 $default = ' selected="selected"';
268 } else {
269 $default = '';
270 }
271 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
272 echo "<option$default value='$arc_row->yyear$arc_row->mmonth'>";
273 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
274 echo esc_html($wp_locale->get_month($arc_row->mmonth)) . " ".esc_html($arc_row->yyear)."";
275 echo "</option>\n";
276 }
277 ?>
278 </select>
279 <?php
280 }
281 ?>
282
283 <select name="posts_per_page" id="posts_per_page">
284 <option <?php if (! isset($_GET['posts_per_page'])) {
285 echo 'selected="selected"';
286 } ?> value=""><?php _e('Quantity&hellip;', 'simple-tags'); ?></option>
287 <option <?php selected($posts_per_page, 10); ?> value="10">10</option>
288 <option <?php selected($posts_per_page, 20); ?> value="20">20</option>
289 <option <?php selected($posts_per_page, 30); ?> value="30">30</option>
290 <option <?php selected($posts_per_page, 40); ?> value="40">40</option>
291 <option <?php selected($posts_per_page, 50); ?> value="50">50</option>
292 <option <?php selected($posts_per_page, 100); ?> value="100">100</option>
293 <option <?php selected($posts_per_page, 200); ?> value="200">200</option>
294 </select>
295
296 <?php
297
298 $current_filter_term = isset($_GET['massedit_filter_term']) ? sanitize_text_field($_GET['massedit_filter_term']) : '';
299 $selected_term_label = '';
300
301 if ($current_filter_term) {
302 $existing_term = get_term_by('slug', $current_filter_term, SimpleTags_Admin::$taxonomy);
303 if ($existing_term && !is_wp_error($existing_term)) {
304 $show_slug = (int) SimpleTags_Plugin::get_option_value('enable_mass-edit_terms_slug') === 1;
305
306 if ($show_slug) {
307 $selected_term_label = sprintf('%s (%s)', $existing_term->name, $existing_term->slug);
308 } else {
309 $selected_term_label = $existing_term->name;
310 }
311 }
312 }
313 ?>
314
315 <select name="massedit_filter_term" id="<?php echo esc_attr(SimpleTags_Admin::$taxonomy); ?>"
316 class="taxopress-select2-term-filter"
317 data-placeholder="<?php echo esc_attr__('Filter by term', 'simple-tags'); ?>"
318 style="min-width:200px;">
319 <option value=""><?php esc_html_e('All terms', 'simple-tags'); ?></option>
320 <?php if ($current_filter_term && $selected_term_label) : ?>
321 <option value="<?php echo esc_attr($current_filter_term); ?>" selected="selected">
322 <?php echo esc_html($selected_term_label); ?>
323 </option>
324 <?php endif; ?>
325 </select>
326
327 <input type="submit" id="post-query-submit" value="<?php _e('Filter', 'simple-tags'); ?>"
328 class="button-secondary"/>
329 <?php } ?>
330 <?php SimpleTags_Admin::boxSelectorTaxonomy('st_mass_terms'); ?>
331 </div>
332 <br style="clear:both;"/>
333 </div>
334 </form>
335
336 <div style="clear:both;margin-bottom: 6px;"></div>
337
338 <?php if (have_posts()) :
339 add_filter('the_title', 'esc_html');
340 ?>
341 <form name="post" id="post" method="post" class="st-mass-edit">
342 <table class="widefat post fixed">
343 <thead>
344 <tr>
345 <th class="manage-column"><?php esc_html_e('Post title', 'simple-tags'); ?></th>
346 <th class="manage-column"><?php printf(esc_html__('Terms : %s', 'simple-tags'), esc_html(SimpleTags_Admin::$taxo_name)); ?></th>
347 </tr>
348 </thead>
349 <tbody>
350 <?php
351 $class = 'alternate';
352 while (have_posts()) {
353 the_post();
354 $class = ($class == 'alternate') ? '' : 'alternate';
355 ?>
356 <tr valign="top" class="<?php echo esc_attr($class); ?>">
357 <th scope="row"><a
358 href="<?php echo esc_url(admin_url('post.php?action=edit&amp;post=' . get_the_ID())); ?>"
359 title="<?php esc_attr_e('Edit', 'simple-tags'); ?>"><?php echo (esc_html(get_the_title()) == '') ? (int)get_the_ID() : esc_html(get_the_title()); ?></a>
360 </th>
361 <td><input id="tags-input<?php the_ID(); ?>" class="autocomplete-input tags_input taxopress-mass-edit-input"
362 type="text" size="100" name="tags[<?php echo (int)get_the_ID(); ?>]"
363 value="<?php echo esc_attr(SimpleTags_Admin::getTermsToEdit(SimpleTags_Admin::$taxonomy, get_the_ID())); ?>"/>
364 </td>
365 </tr>
366 <?php
367 }
368 ?>
369 </tbody>
370 </table>
371
372 <p class="submit">
373 <input type="hidden" name="secure_mass"
374 value="<?php echo esc_attr(wp_create_nonce('st_mass_terms')); ?>"/>
375 <input class="button-primary" type="submit" name="update_mass"
376 value="<?php esc_attr_e('Update all &raquo;', 'simple-tags'); ?>"/>
377 </p>
378 </form>
379
380 <?php else: ?>
381
382 <p><?php _e('No content to edit.', 'simple-tags'); ?>
383
384 <?php endif; ?>
385
386 <?php SimpleTags_Admin::printAdminFooter(); ?>
387 </div>
388
389 <div class="taxopress-right-sidebar admin-settings-sidebar">
390 <?php do_action('taxopress_admin_after_sidebar'); ?>
391 </div>
392
393 </div>
394
395 <?php
396 do_action('simpletags-mass_terms', SimpleTags_Admin::$taxonomy);
397 }
398
399 /**
400 * Clone the core WP function, add the possibility to manage the post type
401 *
402 * @param bool $q
403 *
404 * @return array
405 * @author WebFactory Ltd
406 */
407 public static function edit_data_query($q = false)
408 {
409 if (false === $q) {
410 $q = $_GET;
411 }
412
413 if (! isset($q['massedit_filter_term'])) {
414 $q['massedit_filter_term'] = '';
415 }
416
417 // Date
418 if (isset($q['m'])) {
419 $q['m'] = (int) $q['m'];
420 }
421
422 // Category
423 if (isset($q['cat'])) {
424 $q['cat'] = (int) $q['cat'];
425 }
426
427 // Quantity
428 $q['posts_per_page'] = (isset($q['posts_per_page'])) ? (int) $q['posts_per_page'] : 0;
429 if ($q['posts_per_page'] == 0) {
430 $q['posts_per_page'] = 15;
431 }
432
433 // Content type
434 $q['post_type'] = SimpleTags_Admin::$post_type;
435
436 // Post status
437 $post_stati = array( // array( adj, noun )
438 'publish' => array(
439 _x('Published', 'post'),
440 __('Published posts'),
441 _n_noop('Published <span class="count">(%s)</span>', 'Published <span class="count">(%s)</span>')
442 ),
443 'future' => array(
444 _x('Scheduled', 'post'),
445 __('Scheduled posts'),
446 _n_noop('Scheduled <span class="count">(%s)</span>', 'Scheduled <span class="count">(%s)</span>')
447 ),
448 'pending' => array(
449 _x('Pending Review', 'post'),
450 __('Pending posts'),
451 _n_noop('Pending Review <span class="count">(%s)</span>', 'Pending Review <span class="count">(%s)</span>')
452 ),
453 'draft' => array(
454 _x('Draft', 'post'),
455 _x('Drafts', 'manage posts header'),
456 _n_noop('Draft <span class="count">(%s)</span>', 'Drafts <span class="count">(%s)</span>')
457 ),
458 'private' => array(
459 _x('Private', 'post'),
460 __('Private posts'),
461 _n_noop('Private <span class="count">(%s)</span>', 'Private <span class="count">(%s)</span>')
462 ),
463 'inherit' => array(
464 _x('Inherit', 'post'),
465 __('Inherit posts'),
466 _n_noop('Inherit <span class="count">(%s)</span>', 'Inherit <span class="count">(%s)</span>')
467 ),
468 );
469
470 $post_stati = apply_filters('post_stati', $post_stati);
471 $avail_post_stati = get_available_post_statuses(SimpleTags_Admin::$post_type);
472
473
474 if ($q['post_type'] === 'attachment') {
475 $q['post_status'] = 'inherit';
476 }
477
478 $post_status_q = '';
479 if (isset($q['post_status']) && in_array($q['post_status'], array_keys($post_stati))) {
480 $post_status_q = '&post_status=' . $q['post_status'];
481 $post_status_q .= '&perm=readable';
482 } elseif (! isset($q['post_status'])) {
483 $q['post_status'] = '';
484 }
485
486
487 if ('pending' === $q['post_status']) {
488 $order = 'ASC';
489 $orderby = 'modified';
490 } elseif ('draft' === $q['post_status']) {
491 $order = 'DESC';
492 $orderby = 'modified';
493 } else {
494 $order = 'DESC';
495 $orderby = 'date';
496 }
497
498 $args = array(
499 'post_type' => $q['post_type'],
500 'what_to_show' => 'posts',
501 'posts_per_page' => $q['posts_per_page'],
502 'order' => $order,
503 'orderby' => $orderby,
504 );
505
506 if (! empty($q['post_status']) && in_array($q['post_status'], array_keys($post_stati), true)) {
507 $args['post_status'] = $q['post_status'];
508 $args['perm'] = 'readable';
509 }
510
511 if (! empty($q['s'])) {
512 $args['s'] = sanitize_text_field($q['s']);
513 }
514
515 if (! empty($q['m']) && (int) $q['m'] > 0) {
516 $args['m'] = (int) $q['m'];
517 }
518
519 if (! empty($q['massedit_filter_term'])) {
520 $args['tax_query'] = array(
521 array(
522 'taxonomy' => SimpleTags_Admin::$taxonomy,
523 'field' => 'slug',
524 'terms' => sanitize_text_field($q['massedit_filter_term']),
525 ),
526 );
527 }
528
529 query_posts($args);
530
531 return array( $post_stati, $avail_post_stati );
532 }
533
534 }
535