| 1 |
<?php |
| 2 |
|
| 3 |
class SimpleTags_Terms |
| 4 |
{ |
| 5 |
public const MENU_SLUG = 'st_options'; |
| 6 |
|
| 7 |
// class instance |
| 8 |
public static $instance; |
| 9 |
|
| 10 |
// WP_List_Table object |
| 11 |
public $terms_table; |
| 12 |
|
| 13 |
/** |
| 14 |
* Constructor |
| 15 |
* |
| 16 |
* @return void |
| 17 |
* @author Olatechpro |
| 18 |
*/ |
| 19 |
public function __construct() |
| 20 |
{ |
| 21 |
|
| 22 |
global $hook_suffix; //avoid warning outputs |
| 23 |
if (!isset($hook_suffix)) { |
| 24 |
$hook_suffix = ''; |
| 25 |
} |
| 26 |
|
| 27 |
add_filter('set-screen-option', [__CLASS__, 'set_screen'], 10, 3); |
| 28 |
// Admin menu |
| 29 |
add_action('admin_menu', [$this, 'admin_menu']); |
| 30 |
// Javascript |
| 31 |
add_action('admin_enqueue_scripts', [__CLASS__, 'admin_enqueue_scripts'], 11); |
| 32 |
//support post type for terms query |
| 33 |
add_filter('terms_clauses', [__CLASS__, 'taxopress_terms_clauses'], 10, 3); |
| 34 |
//inline term edit |
| 35 |
add_action('wp_ajax_taxopress_terms_inline_save_term', [$this, 'taxopress_terms_inline_save_term_callback']); |
| 36 |
} |
| 37 |
|
| 38 |
// Handle the post_type parameter given in get_terms function |
| 39 |
public static function taxopress_terms_clauses($clauses, $taxonomy, $args) |
| 40 |
{ |
| 41 |
// phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 42 |
if (isset($_REQUEST['page']) && $_REQUEST['page'] === 'st_terms' && !empty($args['post_types']) && is_array($args['post_types'])) { |
| 43 |
global $wpdb; |
| 44 |
|
| 45 |
$post_types = array(); |
| 46 |
|
| 47 |
foreach ($args['post_types'] as $cpt) { |
| 48 |
$post_types[] = "'" . esc_sql(sanitize_key($cpt)) . "'"; |
| 49 |
} |
| 50 |
|
| 51 |
if (!empty($post_types)) { |
| 52 |
$clauses['fields'] = 'DISTINCT ' . str_replace('tt.*', 'tt.term_taxonomy_id, tt.term_id, tt.taxonomy, tt.description, tt.parent', $clauses['fields']) . ', COUNT(t.term_id) AS count'; |
| 53 |
$clauses['join'] .= ' INNER JOIN ' . $wpdb->term_relationships . ' AS r ON r.term_taxonomy_id = tt.term_taxonomy_id INNER JOIN ' . $wpdb->posts . ' AS p ON p.ID = r.object_id'; |
| 54 |
$clauses['where'] .= ' AND p.post_type IN (' . implode(',', $post_types) . ')'; |
| 55 |
$clauses['orderby'] = 'GROUP BY t.term_id ' . $clauses['orderby']; |
| 56 |
} |
| 57 |
} |
| 58 |
return $clauses; |
| 59 |
} |
| 60 |
|
| 61 |
/** |
| 62 |
* Init somes JS and CSS need for this feature |
| 63 |
* |
| 64 |
* @return void |
| 65 |
* @author Olatechpro |
| 66 |
*/ |
| 67 |
public static function admin_enqueue_scripts() |
| 68 |
{ |
| 69 |
|
| 70 |
// add JS for manage click tags |
| 71 |
// phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 72 |
if (isset($_GET['page']) && $_GET['page'] == 'st_terms') { |
| 73 |
wp_enqueue_style('st-taxonomies-css'); |
| 74 |
wp_enqueue_script('admin-tags'); |
| 75 |
wp_enqueue_script('inline-edit-tax'); |
| 76 |
} |
| 77 |
} |
| 78 |
|
| 79 |
|
| 80 |
public function taxopress_terms_inline_save_term_callback() |
| 81 |
{ |
| 82 |
global $wpdb; |
| 83 |
|
| 84 |
check_ajax_referer('taxinlineeditnonce', '_inline_edit'); |
| 85 |
|
| 86 |
if (!isset($_POST['edit_taxonomy'], $_POST['original_tax'])) { |
| 87 |
wp_die(-1); |
| 88 |
} |
| 89 |
|
| 90 |
$edit_taxonomy = sanitize_key(wp_unslash($_POST['edit_taxonomy'])); |
| 91 |
$taxonomy = sanitize_key(wp_unslash($_POST['original_tax'])); |
| 92 |
$tax = get_taxonomy($taxonomy); |
| 93 |
$edit_tax = get_taxonomy($edit_taxonomy); |
| 94 |
|
| 95 |
if (!$tax || !$edit_tax) { |
| 96 |
wp_die(0); |
| 97 |
} |
| 98 |
|
| 99 |
if (!isset($_POST['tax_ID']) || !(int) $_POST['tax_ID']) { |
| 100 |
wp_die(-1); |
| 101 |
} |
| 102 |
|
| 103 |
$id = (int) $_POST['tax_ID']; |
| 104 |
|
| 105 |
if (!current_user_can('edit_term', $id)) { |
| 106 |
wp_die(-1); |
| 107 |
} |
| 108 |
|
| 109 |
$tag = get_term($id, $taxonomy); |
| 110 |
$_POST['description'] = $tag->description; |
| 111 |
|
| 112 |
$updated = wp_update_term($id, $taxonomy, $_POST); |
| 113 |
|
| 114 |
if ($updated && !is_wp_error($updated)) { |
| 115 |
$tag = get_term($updated['term_id'], $taxonomy); |
| 116 |
if (!$tag || is_wp_error($tag)) { |
| 117 |
if (is_wp_error($tag) && $tag->get_error_message()) { |
| 118 |
wp_die(esc_html($tag->get_error_message())); |
| 119 |
} |
| 120 |
wp_die(esc_html__('Item not updated.')); |
| 121 |
} else { |
| 122 |
if ($tax !== $edit_tax) { |
| 123 |
$update_term = $wpdb->update( |
| 124 |
$wpdb->prefix . 'term_taxonomy', |
| 125 |
['taxonomy' => $edit_taxonomy], |
| 126 |
['term_taxonomy_id' => $tag->term_taxonomy_id], |
| 127 |
['%s'], |
| 128 |
['%d'] |
| 129 |
); |
| 130 |
if ($update_term) { |
| 131 |
clean_term_cache($tag->term_id); |
| 132 |
$tag = get_term($tag->term_id, $edit_taxonomy); |
| 133 |
} |
| 134 |
} |
| 135 |
} |
| 136 |
} else { |
| 137 |
wp_die(esc_html__('Error updating term.')); |
| 138 |
} |
| 139 |
|
| 140 |
$wp_list_table = new Taxopress_Terms_List(); |
| 141 |
|
| 142 |
$wp_list_table->single_row($tag); |
| 143 |
wp_die(); |
| 144 |
} |
| 145 |
|
| 146 |
|
| 147 |
public static function set_screen($status, $option, $value) |
| 148 |
{ |
| 149 |
return $value; |
| 150 |
} |
| 151 |
|
| 152 |
/** Singleton instance */ |
| 153 |
public static function get_instance() |
| 154 |
{ |
| 155 |
if (!isset(self::$instance)) { |
| 156 |
self::$instance = new self(); |
| 157 |
} |
| 158 |
|
| 159 |
return self::$instance; |
| 160 |
} |
| 161 |
|
| 162 |
/** |
| 163 |
* Add WP admin menu for Tags |
| 164 |
* |
| 165 |
* @return void |
| 166 |
* @author Olatechpro |
| 167 |
*/ |
| 168 |
public function admin_menu() |
| 169 |
{ |
| 170 |
$hook = add_submenu_page( |
| 171 |
self::MENU_SLUG, |
| 172 |
esc_html__('Terms', 'simple-tags'), |
| 173 |
esc_html__('Terms', 'simple-tags'), |
| 174 |
'simple_tags', |
| 175 |
'st_terms', |
| 176 |
[ |
| 177 |
$this, |
| 178 |
'page_manage_terms', |
| 179 |
] |
| 180 |
); |
| 181 |
|
| 182 |
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reading non-state-modifying GET parameter for action inspection |
| 183 |
if (taxopress_is_screen_main_page() && (!isset($_GET['action']) || $_GET['action'] !== 'new_item')) { |
| 184 |
add_action("load-$hook", [$this, 'screen_option']); |
| 185 |
} |
| 186 |
} |
| 187 |
|
| 188 |
/** |
| 189 |
* Screen options |
| 190 |
*/ |
| 191 |
public function screen_option() |
| 192 |
{ |
| 193 |
|
| 194 |
|
| 195 |
$option = 'per_page'; |
| 196 |
$args = [ |
| 197 |
'label' => esc_html__('Number of items per page', 'simple-tags'), |
| 198 |
'default' => 20, |
| 199 |
'option' => 'st_terms_per_page' |
| 200 |
]; |
| 201 |
|
| 202 |
add_screen_option($option, $args); |
| 203 |
|
| 204 |
|
| 205 |
$this->terms_table = new Taxopress_Terms_List(); |
| 206 |
} |
| 207 |
|
| 208 |
/** |
| 209 |
* Method for build the page HTML manage tags |
| 210 |
* |
| 211 |
* @return void |
| 212 |
* @author Olatechpro |
| 213 |
*/ |
| 214 |
public function page_manage_terms() |
| 215 |
{ |
| 216 |
// Default order |
| 217 |
// phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 218 |
if (!isset($_GET['orderby'])) { |
| 219 |
$_GET['orderby'] = 'name'; |
| 220 |
} |
| 221 |
// phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 222 |
if (!isset($_GET['order'])) { |
| 223 |
$_GET['order'] = 'asc'; |
| 224 |
} |
| 225 |
|
| 226 |
settings_errors(__CLASS__); |
| 227 |
|
| 228 |
?> |
| 229 |
<div class="wrap st_wrap st-manage-taxonomies-page manage-taxopress-terms"> |
| 230 |
|
| 231 |
<div id=""> |
| 232 |
|
| 233 |
<?php |
| 234 |
// phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 235 |
if (isset($_GET['action']) && $_GET['action'] === 'new_item') { |
| 236 |
?> |
| 237 |
<div class="taxopress-term-wrap"> |
| 238 |
<div class="taxopress-term-main"> |
| 239 |
<h1 class="wp-heading-inline"><?php esc_html_e('Terms', 'simple-tags'); ?></h1> |
| 240 |
<div class="taxopress-description"> |
| 241 |
<?php esc_html_e('This screen allows you to search and edit all the terms on your site.', 'simple-tags'); ?> |
| 242 |
</div> |
| 243 |
<?php |
| 244 |
do_action('taxopress_terms_copy_with_metadata_promo'); |
| 245 |
?> |
| 246 |
</div> |
| 247 |
<div class="taxopress-right-sidebar"> |
| 248 |
<?php do_action('taxopress_admin_after_sidebar'); ?> |
| 249 |
</div> |
| 250 |
</div> |
| 251 |
<?php |
| 252 |
} else { |
| 253 |
?> |
| 254 |
<?php |
| 255 |
|
| 256 |
$taxonomy_heading = ''; |
| 257 |
$show_order_message = false; |
| 258 |
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reading non-state-modifying REQUEST parameter for taxonomy filtering |
| 259 |
if (!empty($_REQUEST['taxopress_terms_taxonomy'])) { |
| 260 |
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reading non-state-modifying REQUEST parameter for taxonomy filtering |
| 261 |
$taxonomy_obj = get_taxonomy(sanitize_text_field(wp_unslash($_REQUEST['taxopress_terms_taxonomy']))); |
| 262 |
if ($taxonomy_obj) { |
| 263 |
$taxonomy_heading = $taxonomy_obj->labels->name; |
| 264 |
$show_order_message = true; |
| 265 |
} |
| 266 |
} |
| 267 |
?> |
| 268 |
<h1 class="wp-heading-inline"> |
| 269 |
<?php |
| 270 |
if ($taxonomy_heading) { |
| 271 |
echo esc_html($taxonomy_heading); |
| 272 |
} else { |
| 273 |
esc_html_e('Terms', 'simple-tags'); |
| 274 |
} |
| 275 |
?> |
| 276 |
</h1> |
| 277 |
<div class="taxopress-description"> |
| 278 |
<?php |
| 279 |
if ($show_order_message) { |
| 280 |
esc_html_e('This screen allows you to order terms via drag and drop.', 'simple-tags'); |
| 281 |
} else { |
| 282 |
esc_html_e('This screen allows you to search and edit all the terms on your site.', 'simple-tags'); |
| 283 |
} |
| 284 |
?> |
| 285 |
</div> |
| 286 |
|
| 287 |
<?php |
| 288 |
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reading non-state-modifying REQUEST parameter for search filtering |
| 289 |
if (isset($_REQUEST['s']) && $search = esc_attr(sanitize_text_field(wp_unslash($_REQUEST['s'])))) { |
| 290 |
/* translators: %s: search keywords */ |
| 291 |
printf(' <span class="subtitle">' . esc_html__( |
| 292 |
'Search results for “%s”', |
| 293 |
'simple-tags' |
| 294 |
) . '</span>', esc_html($search)); |
| 295 |
} |
| 296 |
?> |
| 297 |
<?php |
| 298 |
|
| 299 |
//the terms table instance |
| 300 |
$this->terms_table->prepare_items(); |
| 301 |
?> |
| 302 |
|
| 303 |
|
| 304 |
<hr class="wp-header-end"> |
| 305 |
<div id="ajax-response"></div> |
| 306 |
<form class="search-form wp-clearfix st-taxonomies-search-form" method="get"> |
| 307 |
<?php |
| 308 |
// Hide search box if taxopress_show_all=1 |
| 309 |
$this->terms_table->search_box(esc_html__('Search Terms', 'simple-tags'), 'term'); |
| 310 |
|
| 311 |
?> |
| 312 |
</form> |
| 313 |
<div class="clear"></div> |
| 314 |
|
| 315 |
<div id="col-container" class="wp-clearfix"> |
| 316 |
|
| 317 |
<div class="col-wrap"> |
| 318 |
<form action="<?php echo esc_url(add_query_arg('', '')); ?>" method="post"> |
| 319 |
<?php |
| 320 |
$this->terms_table->display(); |
| 321 |
?> |
| 322 |
</form> |
| 323 |
<div class="form-wrap edit-term-notes"> |
| 324 |
<p><?php esc_html__('Description here.', 'simple-tags') ?></p> |
| 325 |
</div> |
| 326 |
</div> |
| 327 |
|
| 328 |
|
| 329 |
</div> |
| 330 |
|
| 331 |
|
| 332 |
</div> |
| 333 |
<?php $this->terms_table->inline_edit(); ?> |
| 334 |
|
| 335 |
<script> |
| 336 |
(function($) { |
| 337 |
'use strict'; |
| 338 |
|
| 339 |
$(document).ready(function() { |
| 340 |
// ------------------------------------------------------------- |
| 341 |
// TaxoPress terms quick edit |
| 342 |
// ------------------------------------------------------------- |
| 343 |
$(document).on('click', 'a.editinline, button.editinline', function(e) { |
| 344 |
var term_id = $(this).attr('data-term-id'); |
| 345 |
var taxonomy = $(this).attr('data-taxonomy'); |
| 346 |
$('.inline-edit-row#edit-' + term_id).find('select[name="edit_taxonomy"]').val(taxonomy); |
| 347 |
}); |
| 348 |
}); |
| 349 |
|
| 350 |
})(jQuery); |
| 351 |
</script> |
| 352 |
<?php SimpleTags_Admin::printAdminFooter(); ?> |
| 353 |
</div> |
| 354 |
<?php |
| 355 |
} |
| 356 |
?> |
| 357 |
<?php |
| 358 |
} |
| 359 |
} |
| 360 |
|