PluginProbe
Tag, Category, and Taxonomy Manager – Autotagger Automatically Add Terms / 3.42.0
Tag, Category, and Taxonomy Manager – Autotagger Automatically Add Terms v3.42.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.php

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

1,540 lines 59.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 // Include modules
3 require_once (TAXOPRESS_ABSPATH . '/modules/taxopress-ai/taxopress-ai.php');
4
5 class SimpleTags_Admin
6 {
7 // CPT and Taxonomy support
8 public static $post_type = 'post';
9 public static $post_type_name = '';
10 public static $taxonomy = '';
11 public static $taxo_name = '';
12 public static $admin_url = '';
13 public static $enabled_menus = [];
14
15 const MENU_SLUG = 'st_options';
16
17 /**
18 * Initialize Admin
19 *
20 * @return void
21 * @author WebFactory Ltd
22 */
23 public function __construct()
24 {
25 // DB Upgrade ?
26 self::upgrade();
27
28 // Which taxo ?
29 self::register_taxonomy();
30
31 // Plugin installer
32 add_action('admin_init', array(__CLASS__, 'plugin_installer_upgrade_code'));
33
34 // Redirect on plugin activation
35 add_action('admin_init', array(__CLASS__, 'redirect_on_activate'));
36
37 // Admin menu
38 add_action('admin_menu', array(__CLASS__, 'admin_menu'));
39
40 //Admin footer credit
41 add_action('in_admin_footer', array(__CLASS__, 'taxopress_admin_footer'));
42
43 // Load JavaScript and CSS
44 add_action('admin_enqueue_scripts', array(__CLASS__, 'admin_enqueue_scripts'));
45
46 add_action( 'admin_enqueue_scripts', [$this, 'maybe_enqueue_frontend_assets_in_admin'] );
47
48 add_action('admin_head', array($this, 'taxopress_hide_other_plugin_notices'));
49
50 add_action('wp_ajax_taxopress_search_posts', [$this, 'taxopress_search_posts_ajax']);
51
52 //ui class is used accross many pages. So, it should be here
53 require STAGS_DIR . '/inc/class.admin.taxonomies.ui.php';
54
55 $dashboard_screen = (isset($_GET['page']) && $_GET['page'] === 'st_dashboard') ? true : false;
56
57 //dashboard
58 require STAGS_DIR . '/inc/dashboard.php';
59 SimpleTags_Dashboard::get_instance();
60 self::$enabled_menus['st_dashboard'] = esc_html__('Dashboard', 'simple-tags');
61 if (1 === (int) SimpleTags_Plugin::get_option_value('active_taxonomies')) {
62 self::$enabled_menus['st_taxonomies'] = esc_html__('Taxonomies', 'simple-tags');
63 }
64
65 //hidden-terms
66 if (1 === (int) SimpleTags_Plugin::get_option_value('enable_hidden_terms')) {
67 require STAGS_DIR . '/inc/hidden-terms.php';
68 SimpleTags_Hidden_Terms::get_instance();
69 }
70
71 //terms
72 if ($dashboard_screen || 1 === (int) SimpleTags_Plugin::get_option_value('active_st_terms')) {
73 require STAGS_DIR . '/inc/terms-table.php';
74 require STAGS_DIR . '/inc/terms.php';
75 SimpleTags_Terms::get_instance();
76 self::$enabled_menus['st_terms'] = esc_html__('Terms', 'simple-tags');
77 }
78
79 //posts
80 if ($dashboard_screen || 1 === (int) SimpleTags_Plugin::get_option_value('active_st_posts')) {
81 require STAGS_DIR . '/inc/posts-table.php';
82 require STAGS_DIR . '/inc/posts.php';
83 SimpleTags_Posts::get_instance();
84 self::$enabled_menus['st_posts'] = esc_html__('Posts', 'simple-tags');
85 }
86
87 //tag clouds/ terms display
88 if ($dashboard_screen || 1 === (int) SimpleTags_Plugin::get_option_value('active_terms_display')) {
89 require_once STAGS_DIR . '/inc/tag-clouds-action.php';
90 require STAGS_DIR . '/inc/tag-clouds-table.php';
91 require STAGS_DIR . '/inc/tag-clouds.php';
92 SimpleTags_Tag_Clouds::get_instance();
93 }
94
95 //post tags
96 if ($dashboard_screen || 1 === (int) SimpleTags_Plugin::get_option_value('active_post_tags')) {
97 require_once STAGS_DIR . '/inc/post-tags-action.php';
98 require STAGS_DIR . '/inc/post-tags-table.php';
99 require STAGS_DIR . '/inc/post-tags.php';
100 SimpleTags_Post_Tags::get_instance();
101 }
102
103 //Related Posts
104 if ($dashboard_screen || 1 === (int) SimpleTags_Plugin::get_option_value('active_related_posts_new')) {
105 require_once STAGS_DIR . '/inc/related-posts-action.php';
106 require STAGS_DIR . '/inc/related-posts-table.php';
107 require STAGS_DIR . '/inc/related-posts.php';
108 SimpleTags_Related_Post::get_instance();
109 }
110
111 //Auto Links
112 if ($dashboard_screen || 1 === (int) SimpleTags_Plugin::get_option_value('active_auto_links')) {
113 require STAGS_DIR . '/inc/autolinks-table.php';
114 require STAGS_DIR . '/inc/autolinks.php';
115 SimpleTags_Autolink::get_instance();
116 }
117
118 //Auto Terms
119 if ($dashboard_screen || 1 === (int) SimpleTags_Plugin::get_option_value('active_auto_terms')) {
120 require STAGS_DIR . '/inc/autoterms-table.php';
121 require STAGS_DIR . '/inc/autoterms-logs-table.php';
122 require STAGS_DIR . '/inc/autoterms.php';
123 require STAGS_DIR . '/inc/autoterms_content.php';
124 SimpleTags_Autoterms::get_instance();
125 SimpleTags_Autoterms_Content::get_instance();
126 self::$enabled_menus['st_autoterms'] = esc_html__('Auto Terms', 'simple-tags');
127 }
128
129 TaxoPress_AI_Module::get_instance();
130
131 //click terms option
132 require STAGS_DIR . '/inc/class.admin.clickterms.php';
133 new SimpleTags_Admin_ClickTags();
134
135 require STAGS_DIR . '/inc/class.admin.autocomplete.php';
136 new SimpleTags_Admin_Autocomplete();
137
138 // Mass edit terms
139 if ($dashboard_screen || 1 === (int) SimpleTags_Plugin::get_option_value('active_mass_edit')) {
140 require STAGS_DIR . '/inc/class.admin.mass.php';
141 new SimpleTags_Admin_Mass();
142 }
143
144 // Manage terms
145 if ($dashboard_screen || 1 === (int) SimpleTags_Plugin::get_option_value('active_manage')) {
146 require STAGS_DIR . '/inc/class-tag-table.php';
147 require STAGS_DIR . '/inc/class.admin.manage.php';
148 SimpleTags_Admin_Manage::get_instance();
149 }
150
151 require STAGS_DIR . '/inc/class.admin.post.php';
152 new SimpleTags_Admin_Post_Settings();
153
154 //taxonomies
155 if ($dashboard_screen || 1 === (int) SimpleTags_Plugin::get_option_value('active_taxonomies')) {
156 require_once STAGS_DIR . '/inc/taxonomies-action.php';
157 require STAGS_DIR . '/inc/class-taxonomies-table.php';
158 require STAGS_DIR . '/inc/taxonomies.php';
159 SimpleTags_Admin_Taxonomies::get_instance();
160 }
161
162 do_action('taxopress_admin_class_after_includes');
163
164 // Ajax action, JS Helper and admin action
165 add_action('wp_ajax_simpletags', array(__CLASS__, 'ajax_check'));
166 // Save dashboard feature
167 add_action('wp_ajax_save_taxopress_dashboard_feature_by_ajax', [__CLASS__, 'saveDashboardFeature']);
168 // Plugin action links
169 add_filter('plugin_action_links_' . plugin_basename(TAXOPRESS_FILE), [__CLASS__, 'plugin_settings_link']);
170 }
171
172 public function taxopress_hide_other_plugin_notices() {
173 global $pagenow;
174
175 $taxopress_pages = taxopress_admin_pages();
176
177 if (isset($_GET['page']) && in_array($_GET['page'], $taxopress_pages)) {
178 echo '<style>
179 .notice:not(.taxopress-notice) {
180 display: none !important;
181 }
182 </style>';
183 }
184 }
185
186 /**
187 * Plugin action links
188 */
189 public static function plugin_settings_link($links) {
190
191 foreach (self::$enabled_menus as $menu_slug => $menu_title) {
192 $links[] = '<a href="' . admin_url('admin.php?page=' . $menu_slug) . '">'. $menu_title .'</a>';
193 }
194
195 return $links;
196 }
197
198 /**
199 * Ajax for saving a feature from dashboard page
200 *
201 * Copied from PublishPress Blocks
202 *
203 * @return boolean,void Return false if failure, echo json on success
204 */
205 public static function saveDashboardFeature()
206 {
207 if (!current_user_can('admin_simple_tags')) {
208 wp_send_json(__('No permission!', 'simple-tags'), 403);
209 return false;
210 }
211
212 if (
213 !wp_verify_nonce(
214 sanitize_key($_POST['nonce']),
215 'st-admin-js'
216 )
217 ) {
218 wp_send_json(__('Invalid nonce token!', 'simple-tags'), 400);
219 return false;
220 }
221
222 if (empty($_POST['feature']) || !$_POST['feature']) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
223 wp_send_json(__('Error: wrong data', 'simple-tags'), 400);
224 return false;
225 }
226
227 $feature = sanitize_text_field($_POST['feature']);
228 $new_state = sanitize_text_field($_POST['new_state']);
229
230 SimpleTags_Plugin::set_option_value($feature, $new_state);
231
232 wp_send_json(true, 200);
233 }
234
235 /**
236 * Ajax Dispatcher
237 */
238 public static function ajax_check()
239 {
240 if (isset($_GET['stags_action']) && 'maybe_create_tag' === $_GET['stags_action'] && isset($_GET['tag'])) {
241 self::maybe_create_tag(wp_unslash(sanitize_text_field($_GET['tag'])));
242 }
243 }
244
245 /**
246 * Maybe create a tag, and return the term_id
247 *
248 * @param string $tag_name
249 */
250 public static function maybe_create_tag($tag_name = '')
251 {
252 $term_id = 0;
253 //restore & in tag post
254 $tag_name = sanitize_text_field(str_replace("simpletagand", "&", $tag_name));
255 $result_term = term_exists($tag_name, 'post_tag', 0);
256 if (empty($result_term)) {
257 $result_term = wp_insert_term(
258 $tag_name,
259 'post_tag'
260 );
261
262 if (!is_wp_error($result_term)) {
263 $term_id = (int) $result_term['term_id'];
264 }
265 } else {
266 $term_id = (int) $result_term['term_id'];
267 }
268
269 wp_send_json_success(['term_id' => $term_id]);
270 }
271
272 /**
273 * Ajax for search posts
274 *
275 * @return void
276 */
277 public static function taxopress_search_posts_ajax() {
278 if (!check_ajax_referer('st-admin-js', 'nonce', false)) {
279 wp_send_json_error(['message' => __('Security check failed.', 'simple-tags')]);
280 }
281
282 if (!current_user_can('simple_tags')) {
283 wp_send_json_error(['message' => __('Permission denied.', 'simple-tags')]);
284 }
285
286 $search = isset($_GET['search']) ? sanitize_text_field($_GET['search']) : '';
287 $paged = max(1, intval($_GET['page'] ?? 1));
288 $post_type = 'post';
289
290
291 $query = new WP_Query([
292 'post_type' => $post_type,
293 'post_status' => 'publish',
294 'posts_per_page' => 10,
295 'paged' => $paged,
296 'orderby' => 'date',
297 'order' => 'DESC',
298 'fields' => 'ids'
299 ]);
300
301 $results = [];
302 foreach ($query->posts as $post_id) {
303 $results[] = [
304 'id' => $post_id,
305 'text' => get_the_title($post_id)
306 ];
307 }
308
309 wp_send_json([
310 'results' => $results,
311 'more' => $paged < $query->max_num_pages
312 ]);
313 }
314
315 /**
316 * Test if current URL is not a DEV environnement
317 *
318 * Copy from monsterinsights_is_dev_url(), thanks !
319 *
320 * @param string $url
321 *
322 * @return bool
323 */
324 private static function is_dev_url($url = '')
325 {
326 $is_local_url = false;
327
328 // Trim it up
329 $url = strtolower(trim($url));
330 // Need to get the host...so let's add the scheme so we can use parse_url
331 if (false === strpos($url, 'http://') && false === strpos($url, 'https://')) {
332 $url = 'http://' . $url;
333 }
334
335 $url_parts = wp_parse_url($url);
336 $host = !empty($url_parts['host']) ? $url_parts['host'] : false;
337 if (!empty($url) && !empty($host)) {
338 if (false !== ip2long($host)) {
339 if (!filter_var($host, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
340 $is_local_url = true;
341 }
342 } elseif ('localhost' === $host) {
343 $is_local_url = true;
344 }
345
346 $tlds_to_check = array('.local', ':8888', ':8080', ':8081', '.invalid', '.example', '.test');
347 foreach ($tlds_to_check as $tld) {
348 if (false !== strpos($host, $tld)) {
349 $is_local_url = true;
350 break;
351 }
352 }
353
354 if (substr_count($host, '.') > 1) {
355 $subdomains_to_check = array('dev.', '*.staging.', 'beta.', 'test.');
356 foreach ($subdomains_to_check as $subdomain) {
357 $subdomain = str_replace('.', '(.)', $subdomain);
358 $subdomain = str_replace(array('*', '(.)'), '(.*)', $subdomain);
359 if (preg_match('/^(' . $subdomain . ')/', $host)) {
360 $is_local_url = true;
361 break;
362 }
363 }
364 }
365 }
366
367 return $is_local_url;
368 }
369
370 /**
371 * Init taxonomy class variable, load this action after all actions on init !
372 * Make a public static function for call it from children class...
373 *
374 * @return void
375 * @author WebFactory Ltd
376 */
377 public static function register_taxonomy()
378 {
379 add_action('init', array(__CLASS__, 'init'), 99999999);
380 }
381
382 /**
383 * Put in var class the current taxonomy choose by the user
384 *
385 * @return void
386 * @author WebFactory Ltd
387 */
388 public static function init()
389 {
390 self::$taxo_name = esc_html__('Post tags', 'simple-tags');
391 self::$post_type_name = esc_html__('Posts', 'simple-tags');
392
393 // Custom CPT ?
394 if (isset($_GET['cpt']) && !empty($_GET['cpt']) && post_type_exists(sanitize_text_field($_GET['cpt']))) {
395 $cpt = get_post_type_object(sanitize_text_field($_GET['cpt']));
396 self::$post_type = $cpt->name;
397 self::$post_type_name = $cpt->labels->name;
398 }
399
400 // Get compatible taxo for current post type
401 $compatible_taxonomies = get_object_taxonomies(self::$post_type);
402
403 // Custom taxo ?
404 if (isset($_GET['taxo']) && !empty($_GET['taxo']) && taxonomy_exists(sanitize_text_field($_GET['taxo']))) {
405 $taxo = get_taxonomy(sanitize_text_field($_GET['taxo']));
406
407 // Taxo is compatible ?
408 if (in_array($taxo->name, $compatible_taxonomies)) {
409 self::$taxonomy = $taxo->name;
410 self::$taxo_name = $taxo->labels->name;
411 } else {
412 unset($taxo);
413 }
414 }
415
416 // Default taxo from CPT...
417 if (!isset($taxo) && is_array($compatible_taxonomies) && !empty($compatible_taxonomies)) {
418 // Take post_tag before category
419 if (in_array('post_tag', $compatible_taxonomies, true)) {
420 $taxo = get_taxonomy('post_tag');
421 } else {
422 $taxo = get_taxonomy(current($compatible_taxonomies));
423 }
424
425 self::$taxonomy = $taxo->name;
426 self::$taxo_name = $taxo->labels->name;
427
428 // TODO: Redirect for help user that see the URL...
429 } elseif (!isset($taxo)) {
430 // TODO: We can't wp_die on init as it affect all pages
431 //wp_die(esc_html__('This custom post type not have taxonomies.', 'simple-tags'));
432 }
433
434 // Free memory
435 unset($cpt, $taxo);
436 }
437
438 /**
439 * Build HTML form for allow user to change taxonomy for the current page.
440 *
441 * @param string $page_value
442 *
443 * @return void
444 * @author Olatechpro
445 */
446 public static function boxSelectorTaxonomy($page_value = '')
447 {
448 echo '<div class="box-selector-taxonomy">' . PHP_EOL;
449
450 echo '<div class="change-taxo">' . PHP_EOL;
451 echo '<form action="" method="get">' . PHP_EOL;
452 if (!empty($page_value)) {
453 echo '<input type="hidden" name="page" value="' . esc_attr($page_value) . '" />' . PHP_EOL;
454 }
455 $taxonomies = [];
456 echo '<select name="cpt" id="cpt-select" class="st-cpt-select">' . PHP_EOL;
457 foreach (get_post_types(array('show_ui' => true), 'objects') as $post_type) {
458 $taxonomies_children = get_object_taxonomies($post_type->name);
459 if (empty($taxonomies_children)) {
460 continue;
461 }
462 $taxonomies[$post_type->name] = $taxonomies_children;
463 echo '<option ' . selected($post_type->name, self::$post_type, false) . ' value="' . esc_attr($post_type->name) . '">' . esc_html($post_type->labels->name) . '</option>' . PHP_EOL;
464 }
465 echo '</select>' . PHP_EOL;
466
467 echo '<select name="taxo" id="taxonomy-select" class="st-taxonomy-select">' . PHP_EOL;
468 foreach ($taxonomies as $parent_post => $taxonomy) {
469 if (count($taxonomy) > 0) {
470 foreach ($taxonomy as $tax_name) {
471 $taxonomy = get_taxonomy($tax_name);
472 if (false === (bool) $taxonomy->show_ui) {
473 continue;
474 }
475
476 if (self::$post_type == $parent_post) {
477 $class = "";
478 } else {
479 $class = "st-hide-content";
480 }
481
482 echo '<option ' . selected($tax_name, self::$taxonomy, false) . ' value="' . esc_attr($tax_name) . '" data-post="' . esc_attr($parent_post) . '" class="' . esc_attr($class) . '">' . esc_html($taxonomy->labels->name) . '</option>' . PHP_EOL;
483 }
484 }
485 }
486 echo '</select>' . PHP_EOL;
487
488 echo '<input type="submit" class="button" id="submit-change-taxo" value="' . esc_attr__('Change selection', 'simple-tags') . '" />' . PHP_EOL;
489 echo '</form>' . PHP_EOL;
490 echo '</div>' . PHP_EOL;
491 echo '</div>' . PHP_EOL;
492 }
493
494 public static function tabSelectorTaxonomy($tab_slug = '', $page_slug = '')
495 {
496 $current_taxo = isset($_GET["{$tab_slug}_taxo"]) ? sanitize_text_field($_GET["{$tab_slug}_taxo"]) : get_option("{$tab_slug}_taxo", '');
497 $current_cpt = isset($_GET["{$tab_slug}_cpt"]) ? sanitize_text_field($_GET["{$tab_slug}_cpt"]) : get_option("{$tab_slug}_cpt", '');
498
499 // Fallbacks if not yet set
500 if (empty($current_cpt)) {
501 foreach (get_post_types(['show_ui' => true], 'objects') as $pt) {
502 if (!empty(get_object_taxonomies($pt->name))) {
503 $current_cpt = $pt->name;
504 break;
505 }
506 }
507 }
508 if (empty($current_taxo) && $current_cpt) {
509 $possible_taxos = get_object_taxonomies($current_cpt);
510 if (!empty($possible_taxos)) {
511 $current_taxo = $possible_taxos[0];
512 }
513 }
514
515 // Save for use elsewhere
516 self::$post_type = $current_cpt;
517 self::$taxonomy = $current_taxo;
518
519 // Update $post_type_name dynamically
520 if ($current_cpt) {
521 $post_type_object = get_post_type_object($current_cpt);
522 if ($post_type_object) {
523 self::$post_type_name = $post_type_object->labels->name;
524 }
525 }
526
527 // Save to DB for persistence
528 update_option("{$tab_slug}_taxo", $current_taxo);
529 update_option("{$tab_slug}_cpt", $current_cpt);
530
531 // Build list of post types and taxonomies (only CPTs with taxonomies)
532 $taxonomies = [];
533 echo '<div class="box-selector-taxonomy tab-taxo-filter tab-taxo-filter-' . esc_attr($tab_slug) . '">' . PHP_EOL;
534 echo '<div class="change-taxo">' . PHP_EOL;
535
536 echo '<form action="' . esc_url(admin_url('admin.php')) . '" method="get">' . PHP_EOL;
537 $page = !empty($page_slug) ? $page_slug : (isset($_GET['page']) ? sanitize_text_field($_GET['page']) : 'st_manage');
538 echo '<input type="hidden" name="page" value="' . esc_attr($page) . '" />' . PHP_EOL;
539 echo '<input type="hidden" name="page" value="st_manage" />' . PHP_EOL;
540
541 if (!empty($tab_slug)) {
542 echo '<input type="hidden" name="tab" value="' . esc_attr($tab_slug) . '" />' . PHP_EOL;
543 }
544
545 // CPT dropdown
546 echo '<select name="' . esc_attr($tab_slug) . '_cpt" class="st-cpt-select st-cpt-select-' . esc_attr($tab_slug) . '">' . PHP_EOL;
547 foreach (get_post_types(['show_ui' => true], 'objects') as $post_type) {
548 $taxonomies_children = get_object_taxonomies($post_type->name);
549 if (empty($taxonomies_children)) {
550 continue;
551 }
552 $taxonomies[$post_type->name] = $taxonomies_children;
553 echo '<option ' . selected($post_type->name, $current_cpt, false) . ' value="' . esc_attr($post_type->name) . '">' . esc_html($post_type->labels->name) . '</option>' . PHP_EOL;
554 }
555 echo '</select>' . PHP_EOL;
556
557 // Taxonomy dropdown
558 echo '<select name="' . esc_attr($tab_slug) . '_taxo" class="st-taxonomy-select st-taxonomy-select-' . esc_attr($tab_slug) . '">' . PHP_EOL;
559 foreach ($taxonomies as $parent_post => $taxonomy_list) {
560 foreach ($taxonomy_list as $tax_name) {
561 $taxonomy = get_taxonomy($tax_name);
562 if (false === (bool) $taxonomy->show_ui) {
563 continue;
564 }
565 $class = ($parent_post === $current_cpt) ? '' : 'st-hide-content';
566
567 echo '<option ' . selected($tax_name, $current_taxo, false) .
568 ' value="' . esc_attr($tax_name) . '"' .
569 ' data-post="' . esc_attr($parent_post) . '"' .
570 ' class="' . esc_attr($class) . '">' .
571 esc_html($taxonomy->labels->name) .
572 '</option>' . PHP_EOL;
573 }
574 }
575 echo '</select>' . PHP_EOL;
576
577 echo '<input type="submit" class="button" value="' . esc_attr__('Change selection', 'simple-tags') . '" />' . PHP_EOL;
578 echo '</form>' . PHP_EOL;
579 echo '</div>' . PHP_EOL;
580 echo '</div>' . PHP_EOL;
581 }
582
583 public function maybe_enqueue_frontend_assets_in_admin() {
584
585 $screen = get_current_screen();
586 if (!$screen) {
587 return;
588 }
589
590 if (strpos($screen->id, 'taxopress_page_') === false) {
591 return;
592 }
593
594 $is_edit_mode = isset($_GET['action']) && in_array($_GET['action'], ['edit'], true);
595 if (!$is_edit_mode) {
596 return;
597 }
598
599 $current_page = isset($_GET['page']) ? sanitize_text_field($_GET['page']) : '';
600
601 // List of pages that need preview functionality
602 $preview_pages = [
603 'st_terms_display',
604 'st_related_posts',
605 'st_post_tags',
606 ];
607
608 if (!in_array($current_page, $preview_pages, true)) {
609 return;
610 }
611
612 // Register and enqueue assets
613 wp_register_script('taxopress-frontend-js', STAGS_URL . '/assets/frontend/js/frontend.js', array('jquery'), STAGS_VERSION);
614 wp_register_style('taxopress-frontend-css', STAGS_URL . '/assets/frontend/css/frontend.css', array(), STAGS_VERSION, 'all');
615
616 // Enqueue the assets
617 wp_enqueue_script('taxopress-frontend-js');
618 wp_enqueue_style('taxopress-frontend-css');
619 }
620 /**
621 * Init somes JS and CSS need for TaxoPress.
622 *
623 * @return void
624 * @author WebFactory Ltd
625 */
626 public static function admin_enqueue_scripts()
627 {
628 global $pagenow;
629
630 $select_2_page = false;
631 if ((isset($_GET['page']) && in_array($_GET['page'], ['st_posts', 'st_autolinks', 'st_autoterms', 'st_autoterms_schedule', 'st_terms_display', 'st_related_posts', 'st_post_tags', 'st_mass_terms'])) || in_array($pagenow, ['post.php', 'edit.php', 'post-new.php'])) {
632 $select_2_page = true;
633 }
634
635 do_action('taxopress_admin_class_before_assets_register');
636
637 //color picker style
638 wp_enqueue_style('wp-color-picker');
639
640 // Helper TaxoPress
641 wp_register_script('st-helper-add-tags', STAGS_URL . '/assets/js/helper-add-tags.js', array('jquery'), STAGS_VERSION);
642 wp_register_script('st-helper-options', STAGS_URL . '/assets/js/helper-options.js', array('jquery', 'wp-color-picker'), STAGS_VERSION);
643
644 // Register CSS
645 wp_register_style('st-admin', STAGS_URL . '/assets/css/admin.css', array(), STAGS_VERSION, 'all');
646 wp_register_style('st-admin-global', STAGS_URL . '/assets/css/admin-global.css', array(), STAGS_VERSION, 'all');
647
648 // Register tooltip
649 wp_register_script(
650 'taxopress-admin-tooltip',
651 STAGS_URL . '/assets/lib/tooltip/js/tooltip.min.js',
652 ['jquery'],
653 STAGS_VERSION
654 );
655
656 wp_register_style(
657 'taxopress-admin-tooltip',
658 STAGS_URL . '/assets/lib/tooltip/css/tooltip.min.css',
659 [],
660 STAGS_VERSION
661 );
662
663 //enqueue tooltip
664 wp_enqueue_script('taxopress-admin-tooltip');
665 wp_enqueue_style('taxopress-admin-tooltip');
666
667 // Register Select 2
668 wp_register_script(
669 'taxopress-admin-select2',
670 STAGS_URL . '/assets/lib/select2/js/select2.full.min.js',
671 ['jquery'],
672 STAGS_VERSION
673 );
674
675 wp_register_style(
676 'taxopress-admin-select2',
677 STAGS_URL . '/assets/lib/select2/css/select2.min.css',
678 [],
679 STAGS_VERSION
680 );
681
682 if ($select_2_page) {
683 wp_enqueue_script('taxopress-admin-select2');
684 wp_enqueue_style('taxopress-admin-select2');
685 }
686
687 //Register and enqueue admin js
688 $script_dependencies = ['jquery'];
689 if ($select_2_page) {
690 $script_dependencies[] = 'taxopress-admin-select2';
691 $script_dependencies[] = 'wp-util';
692 }
693
694 $taxopress_pages = taxopress_admin_pages();
695
696 if (isset($_GET['page']) && in_array($_GET['page'], $taxopress_pages)) {
697 wp_enqueue_media();
698 }
699
700 wp_register_script('st-admin-js', STAGS_URL . '/assets/js/admin.js', $script_dependencies, STAGS_VERSION);
701 wp_enqueue_script('st-admin-js');
702 //localize script
703 wp_localize_script('st-admin-js', 'st_admin_localize', [
704 'ajaxurl' => admin_url('admin-ajax.php'),
705 'select_valid' => esc_html__('Please select a valid', 'simple-tags'),
706 'check_nonce' => wp_create_nonce('st-admin-js'),
707 'select_default_label' => esc_html__('Select Default Post Thumb', 'simple-tags'),
708 'use_media_label' => esc_html__('Use this media', 'simple-tags'),
709 'existing_content_admin_label' => esc_html__('Edit the current setting.', 'simple-tags'),
710 'autoterm_admin_url' => admin_url('admin.php?page=st_autoterms'),
711 'no_terms_message' => esc_html__('No terms will be deleted', 'simple-tags'),
712 'terms_count_message' => esc_html__(' terms will be deleted.', 'simple-tags'),
713 'checking_terms_message' => esc_html__('Checking terms...', 'simple-tags'),
714 'terms_error' => esc_html__('An error occurred while checking terms.', 'simple-tags'),
715 'post_required' => esc_html__('Select a post to see a preview.', 'simple-tags'),
716 'save_settings' => esc_html__('Auto Term ID missing. Kindly save the auto term before using this feature.', 'simple-tags'),
717 'delete_label' => esc_html__('Delete', 'simple-tags'),
718 'ai_nonce' => wp_create_nonce('taxopress-ai-ajax-nonce'),
719 'post_title' => '%post_title%',
720 'post_permalink' => '%post_permalink%',
721 'post_date' => '%post_date%',
722 'post_thumb_url' => '%post_thumb_url%',
723 'post_category' => '%post_category%',
724 'post_size' => '%post_size%',
725 'post_color' => '%post_color%',
726 'merge_cancelled' => esc_html__('Merge has been cancelled.', 'simple-tags'),
727 'cancel_label' => esc_html__('Cancel', 'simple-tags'),
728 'paused_label' => esc_html__('Pause.', 'simple-tags'),
729 'continue_label' => esc_html__('Continue', 'simple-tags'),
730 'merge_large_data' => esc_html__('Large dataset detected, terms will be merged in batches of 20!', 'simple-tags'),
731 'merge_none_merged' => esc_html__('No terms were merged.', 'simple-tags'),
732 'batch_merge_progress' => esc_html__('Batch %1$s of %2$s merged.', 'simple-tags'),
733 'terms_merged_text' => esc_html__('terms merged', 'simple-tags'),
734 'posts_updated_text' => esc_html__('posts updated', 'simple-tags'),
735 'merge_success_update' => esc_html__('All terms merged into %s', 'simple-tags'),
736 'ajax_merge_terms_error' => esc_html__('AJAX error on batch', 'simple-tags'),
737 'batch_error_text' => esc_html__('Error on batch %1$s:', 'simple-tags'),
738 'enable_merge_terms_slug' => SimpleTags_Plugin::get_option_value('enable_merge_terms_slug'),
739 'enable_add_terms_slug' => SimpleTags_Plugin::get_option_value('enable_add_terms_slug'),
740 'enable_remove_terms_slug' => SimpleTags_Plugin::get_option_value('enable_remove_terms_slug'),
741 'enable_rename_terms_slug' => SimpleTags_Plugin::get_option_value('enable_rename_terms_slug'),
742 'enable_mass_edit_terms_slug' => SimpleTags_Plugin::get_option_value('enable_mass-edit_terms_slug'),
743 'select_post_label' => esc_html__('Search Posts...', 'simple-tags'),
744 'loading' => esc_html__('Loading...', 'simple-tags'),
745 'preview_error' => esc_html__('Error loading preview', 'simple-tags'),
746 'enable_ibm_watson_ai_source' => SimpleTags_Plugin::get_option_value('enable_ibm_watson_ai_source'),
747 'enable_dandelion_ai_source' => SimpleTags_Plugin::get_option_value('enable_dandelion_ai_source'),
748 'enable_lseg_ai_source' => SimpleTags_Plugin::get_option_value('enable_lseg_ai_source'),
749 'plugin_url' => STAGS_URL,
750 'using_default_text' => __('Using default TaxoPress image', 'simple-tags'),
751 'select_image_label' => esc_html__('Select Media', 'simple-tags'),
752 'change_image_label' => esc_html__('Change Media', 'simple-tags'),
753 'use_default_label' => esc_html__('Use Default', 'simple-tags'),
754 'see_more_suggestions' => esc_html__('See More', 'simple-tags'),
755 'see_less_suggestions' => esc_html__('See Less', 'simple-tags'),
756 'apply_selected' => esc_html__('Apply Selected', 'simple-tags'),
757 'close_suggestions' => esc_html__('Close', 'simple-tags'),
758 'select_suggestion_alert' => esc_html__('Please select at least one suggestion to apply.', 'simple-tags'),
759 'multiple_merge_warning' => esc_html__('You have selected multiple merge suggestions. All selected terms will be merged into a single new term. Do you want to continue?', 'simple-tags'),
760 'no_merge_suggestions' => esc_html__('No merge suggestions found for this taxonomy.', 'simple-tags'),
761 'suggested_terms_title' => esc_html__('Suggested Terms to Merge:', 'simple-tags'),
762 'duplicates_text' => esc_html__('duplicates', 'simple-tags'),
763 'reason_text' => esc_html__('Reason:', 'simple-tags'),
764 'select_all_label' => esc_html__('Select All', 'simple-tags'),
765 'deselect_all_label' => esc_html__('Deselect All', 'simple-tags'),
766 'terms_to_merge_text' => esc_html__('Terms to Merge', 'simple-tags'),
767 'new_term_text' => esc_html__('New Term', 'simple-tags'),
768 'reasons_text' => esc_html__('Reasons', 'simple-tags'),
769 ]);
770
771
772 //Register remodal assets
773 wp_register_script('st-remodal-js', STAGS_URL . '/assets/js/remodal.min.js', array('jquery'), STAGS_VERSION);
774 wp_register_style('st-remodal-css', STAGS_URL . '/assets/css/remodal.css', array(), STAGS_VERSION, 'all');
775 wp_register_style('st-remodal-default-theme-css', STAGS_URL . '/assets/css/remodal-default-theme.css', array(), STAGS_VERSION, 'all');
776
777 // Register location
778 $wp_post_pages = array('post.php', 'post-new.php');
779 $wp_page_pages = array('page.php', 'page-new.php');
780
781 wp_enqueue_style('st-admin-global');
782
783 // Common Helper for Post, Page and Plugin Page
784 if (
785 in_array($pagenow, $wp_post_pages) ||
786 (in_array($pagenow, $wp_page_pages) && is_page_have_tags()) ||
787 (isset($_GET['page']) && in_array($_GET['page'], $taxopress_pages))
788 ) {
789 wp_enqueue_script('st-remodal-js');
790 wp_enqueue_style('st-remodal-css');
791 wp_enqueue_style('st-remodal-default-theme-css');
792 wp_enqueue_style('st-admin');
793
794 do_action('taxopress_admin_class_after_styles_enqueue');
795 }
796
797 // add jQuery tabs for options page. Use jQuery UI Tabs from WP
798 if (isset($_GET['page']) && in_array($_GET['page'], array('st_options', 'st_terms_display', 'st_post_tags', 'st_related_posts',))) {
799 wp_enqueue_script('jquery-ui-tabs');
800 wp_enqueue_script('st-helper-options');
801 }
802
803 do_action('taxopress_admin_class_after_assets_enqueue');
804 }
805
806 /**
807 * Add settings page on WordPress admin menu
808 *
809 * @return void
810 * @author WebFactory Ltd
811 */
812 public static function admin_menu()
813 {
814 self::$admin_url = admin_url('admin.php?page=' . self::MENU_SLUG);
815
816 add_menu_page(
817 __('TaxoPress: Options', 'simple-tags'),
818 __('TaxoPress', 'simple-tags'),
819 'admin_simple_tags',
820 self::MENU_SLUG,
821 array(
822 __CLASS__,
823 'page_options',
824 ),
825 'dashicons-tag',
826 69
827 );
828 add_submenu_page(
829 self::MENU_SLUG,
830 __('TaxoPress: Options', 'simple-tags'),
831 __('Settings', 'simple-tags'),
832 'admin_simple_tags',
833 self::MENU_SLUG,
834 array(
835 __CLASS__,
836 'page_options',
837 )
838 );
839 }
840
841 /**
842 * Build HTML for page options, manage also save/reset settings
843 *
844 * @return void
845 * @author WebFactory Ltd
846 */
847 public static function page_options()
848 {
849 // Get options
850 $options = (array) SimpleTags_Plugin::get_option();
851
852 if (current_user_can('admin_simple_tags')) {
853 // Update or reset options
854 if (isset($_POST['updateoptions'])) {
855 $dashboard_options = taxopress_dashboard_options();
856 $dashboard_option_keys = array_column($dashboard_options, 'option_key');
857
858 check_admin_referer('updateresetoptions-simpletags');
859
860 $sanitized_options = [];
861
862 $is_fast_update_submission = isset($_GET['page']) && $_GET['page'] === 'st_taxopress_ai';
863
864 // This settings has been migrated to fast update screen so only update from there
865 if ($is_fast_update_submission) {
866 // add taxopress ai post type and taxonomies options so we can have all post types. TODO: This need to be a filter
867 foreach (get_post_types(['public' => true], 'names') as $post_type => $post_type_object) {
868 if ($post_type == 'post') {
869 $opt_default_value = 'post_tag';
870 } else {
871 $opt_default_value = 0;
872 }
873 $options['taxopress_ai_' . $post_type . '_metabox_default_taxonomy'] = $opt_default_value;
874 $options['taxopress_ai_' . $post_type . '_metabox_display_option'] = 'default';
875 $options['taxopress_ai_' . $post_type . '_support_private_taxonomy'] = 0;
876
877 $options['taxopress_ai_' . $post_type . '_metabox_orderby'] = 'count';
878 $options['taxopress_ai_' . $post_type . '_metabox_order'] = 'desc';
879 $options['taxopress_ai_' . $post_type . '_metabox_maximum_terms'] = 45;
880 $options['taxopress_ai_' . $post_type . '_metabox_show_post_count'] = 0;
881 $options['taxopress_ai_' . $post_type . '_metabox_show_term_slug'] = 0;
882
883 $options['taxopress_ai_' . $post_type . '_minimum_term_length'] = 2;
884 $options['taxopress_ai_' . $post_type . '_maximum_term_length'] = 40;
885
886 $options['taxopress_ai_' . $post_type . '_exclusions'] = '';
887 $options['enable_taxopress_ai_' . $post_type . '_metabox'] = $opt_default_value;
888 $options['taxopress_ai_' . $post_type . '_metabox_filters'] = 1;
889 foreach (['post_terms', 'existing_terms', 'suggest_local_terms', 'create_terms'] as $taxopress_ai_tab) {
890 $options['enable_taxopress_ai_' . $post_type . '_' . $taxopress_ai_tab . '_tab'] = $opt_default_value;
891 }
892 }
893
894 // add metabox post type and taxonomies options so we can have all post types. TODO: This need to be a filter
895 foreach (taxopress_get_all_wp_roles() as $role_name => $role_info) {
896 if (in_array($role_name, ['administrator', 'editor', 'author', 'contributor'])) {
897 $enable_acess_default_value = 1;
898 } else {
899 $enable_acess_default_value = 0;
900 }
901 $options['enable_' . $role_name . '_metabox'] = $enable_acess_default_value;
902 $options['enable_restrict' . $role_name . '_metabox'] = $enable_acess_default_value;
903
904 // ONLY admin + editor default to can edit
905 if (!isset($options['enable_edit_' . $role_name . '_metabox'])) {
906 $options['enable_edit_' . $role_name . '_metabox'] = in_array($role_name, ['administrator', 'editor']) ? 1 : 0;
907 }
908
909 $options['enable_metabox_' . $role_name . ''] = [];
910 $options['remove_taxonomy_metabox_' . $role_name . ''] = [];
911 }
912 }
913
914 foreach ($options as $key => $value) {
915 // If this is NOT a Fast Update submission, preserve metabox/metabox-access keys
916 if (!$is_fast_update_submission && preg_match('/^(enable_taxopress_ai_|taxopress_ai_|enable_.*_metabox|enable_restrict.*_metabox|enable_edit_.*_metabox|enable_metabox_|remove_taxonomy_metabox_)/', $key)) {
917 // Keep existing value as-is
918 if (!is_array($value)) {
919 $sanitized_options[$key] = taxopress_sanitize_text_field($value);
920 } else {
921 $sanitized_options[$key] = map_deep($value, 'sanitize_text_field');
922 }
923 continue;
924 }
925
926 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
927 $post_value = isset($_POST[$key]) ? $_POST[$key] : '';
928
929 if (empty($post_value) && in_array($key, $dashboard_option_keys)) {
930 $post_value = SimpleTags_Plugin::get_option_value($key);
931 }
932
933 if (!is_array($post_value)) {
934 $sanitized_options[$key] = taxopress_sanitize_text_field($post_value);
935 } else {
936 $sanitized_options[$key] = map_deep($post_value, 'sanitize_text_field');
937 }
938 }
939 $options = $sanitized_options;
940
941 SimpleTags_Plugin::set_option($options);
942
943 do_action('simpletags_settings_save_general_end');
944 do_action('taxopress_settings_saved');
945
946 add_settings_error(__CLASS__, __CLASS__, esc_html__('Options saved', 'simple-tags'), 'updated taxopress-notice');
947 } elseif (isset($_POST['reset_options'])) {
948 check_admin_referer('updateresetoptions-simpletags');
949
950 SimpleTags_Plugin::set_default_option();
951
952 add_settings_error(__CLASS__, __CLASS__, esc_html__('TaxoPress options resetted to default options!', 'simple-tags'), 'updated taxopress-notice');
953 } else {
954 //add_settings_error(__CLASS__, __CLASS__, esc_html__('Settings updated', 'simple-tags'), 'updated');
955 }
956 }
957
958 settings_errors(__CLASS__);
959 include STAGS_DIR . '/views/admin/page-settings.php';
960 }
961
962 /**
963 * Get terms for a post, format terms for input and autocomplete usage
964 *
965 * @param string $taxonomy
966 * @param integer $post_id
967 *
968 * @return string
969 * @author WebFactory Ltd
970 */
971 public static function getTermsToEdit($taxonomy = 'post_tag', $post_id = 0)
972 {
973 $post_id = (int) $post_id;
974 if (!$post_id) {
975 return '';
976 }
977
978 $is_mass_edit_page = isset($_GET['page']) && $_GET['page'] === 'st_mass_terms';
979 $show_slug = SimpleTags_Plugin::get_option_value('enable_mass-edit_terms_slug');
980
981 if ($is_mass_edit_page) {
982 $term_objects = wp_get_post_terms($post_id, $taxonomy);
983 if (empty($term_objects) || is_wp_error($term_objects)) {
984 return '';
985 }
986
987 $terms = array();
988 foreach ($term_objects as $term) {
989 if ($show_slug) {
990 if (!empty($term->slug)) {
991 $terms[] = $term->name . ' (' . $term->slug . ')';
992 } else {
993 $terms[] = $term->name;
994 }
995 } else {
996 $terms[] = $term->name;
997 }
998 }
999
1000 $terms = join(', ', $terms);
1001 } else {
1002
1003 $terms = wp_get_post_terms($post_id, $taxonomy, array('fields' => 'names'));
1004 if (empty($terms) || is_wp_error($terms)) {
1005 return '';
1006 }
1007
1008 $terms = array_unique($terms);
1009 $terms = join(', ', $terms);
1010 }
1011
1012 $terms = esc_attr($terms);
1013 $terms = apply_filters('tags_to_edit', $terms);
1014
1015 return $terms;
1016 }
1017
1018 /**
1019 * Default content for meta box of TaxoPress
1020 *
1021 * @return string
1022 * @author WebFactory Ltd
1023 */
1024 public static function getDefaultContentBox()
1025 {
1026 if ((int) wp_count_terms('post_tag', array('hide_empty' => false)) == 0) { // TODO: Custom taxonomy
1027 return esc_html__('This feature requires at least 1 tag to work. Begin by adding tags!', 'simple-tags');
1028 } else {
1029 return esc_html__('This feature works only with activated JavaScript. Activate it in your Web browser so you can!', 'simple-tags');
1030 }
1031 }
1032
1033 /**
1034 * A short public static function for display the same copyright on all admin pages
1035 *
1036 * @return void
1037 * @author WebFactory Ltd
1038 */
1039 public static function printAdminFooter()
1040 {
1041 /* ?>
1042 <p class="footer_st"><?php printf( __( 'Thanks for using TaxoPress | <a href="https://taxopress.com/">TaxoPress.com</a> | Version %s', 'simple-tags' ), STAGS_VERSION ); ?></p>
1043 <?php */
1044 }
1045
1046 /**
1047 * A short public static function for display the same copyright on all taxopress admin pages
1048 *
1049 * @return void
1050 * @author Olatechpro
1051 */
1052 public static function taxopress_admin_footer()
1053 {
1054
1055 $taxopress_pages = taxopress_admin_pages();
1056
1057 if (isset($_GET['page']) && in_array($_GET['page'], $taxopress_pages)) {
1058 ?>
1059 <p class="footer_st">
1060 <?php
1061 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1062 printf(__('Thanks for using TaxoPress | %1sTaxoPress.com%2s | Version %3s', 'simple-tags'), '<a href="https://taxopress.com/">', '</a>', esc_html(STAGS_VERSION)); ?>
1063 </p>
1064 <?php
1065 }
1066 }
1067
1068 /**
1069 * Ouput formatted options
1070 *
1071 * @param array $option_data
1072 *
1073 * @return string
1074 * @author WebFactory Ltd
1075 */
1076 public static function print_options($option_data)
1077 {
1078 // Get options
1079 $option_actual = SimpleTags_Plugin::get_option();
1080
1081 // Generate output
1082 $output = '';
1083 foreach ($option_data as $section => $options) {
1084 $colspan = count($options) > 1 ? 'colspan="2"' : '';
1085
1086 if ($section === 'legacy') {
1087 $table_sub_tab = '<div class="st-legacy-subtab">
1088 <span class="active" data-content=".legacy-tag-cloud-content">'. esc_html__("Tag Cloud", "simple-tags") .'</span> |
1089 <span data-content=".legacy-post-tags-content">'. esc_html__("Tags for Current Post", "simple-tags") .'</span> |
1090 <span data-content=".legacy-related-posts-content">'. esc_html__("Related Posts", "simple-tags") .'</span> |
1091 <span data-content=".legacy-auto-link-content">'. esc_html__("Auto Links", "simple-tags") .'</span>
1092 </div>' . PHP_EOL;
1093 } elseif ($section === 'taxopress-ai') {
1094 $table_sub_tab_lists = [];
1095 $pt_index = 0;
1096 foreach (TaxoPressAiUtilities::get_post_types_options() as $post_type => $post_type_object) {
1097
1098 if (!in_array($post_type, ['attachment'])) {
1099 $active_pt = ($pt_index === 0) ? 'active' : '';
1100 $table_sub_tab_lists[] = '<span class="' . $active_pt . '" data-content=".taxopress-ai-' . $post_type . '-content">' . esc_html($post_type_object->labels->name) . '</span>';
1101 $pt_index++;
1102 }
1103 }
1104 $table_sub_tab = '<div class="st-taxopress-ai-subtab">' . join(' | ', $table_sub_tab_lists). '</div>' . PHP_EOL;
1105 } elseif ($section === 'metabox') {
1106 $table_sub_tab_lists = [];
1107 $pt_index = 0;
1108 foreach (taxopress_get_all_wp_roles() as $role_name => $role_info) {
1109 $active_pt = ($pt_index === 0) ? 'active' : '';
1110 $table_sub_tab_lists[] = '<span class="' . $active_pt . '" data-content=".metabox-' . $role_name . '-content">' . esc_html(translate_user_role($role_info['name'])) . '</span>';
1111 $pt_index++;
1112 }
1113 $table_sub_tab = '<div class="st-metabox-subtab">' . join(' | ', $table_sub_tab_lists). '</div>' . PHP_EOL;
1114 } else {
1115 $table_sub_tab = '';
1116 }
1117
1118 $output .= '<div class="group" id="' . sanitize_title($section) . '">' . PHP_EOL;
1119 $output .= $table_sub_tab;
1120 $output .= '<fieldset class="options">' . PHP_EOL;
1121 $output .= '<legend>' . self::getNiceTitleOptions($section) . '</legend>' . PHP_EOL;
1122 $output .= '<table class="form-table">' . PHP_EOL;
1123 foreach ((array) $options as $option) {
1124
1125 $class = '';
1126 if (in_array($section, ['legacy', 'taxopress-ai', 'metabox'])) {
1127 $class = $option[5];
1128 }
1129
1130 // Helper
1131 if ($option[2] == 'helper') {
1132 $output .= '<tr style="vertical-align: middle;" class="' . $class . '"><td class="helper stpexplan" ' . $colspan . '>' . stripslashes($option[4]) . '</td></tr>' . PHP_EOL;
1133 continue;
1134 }
1135
1136 // Fix notices
1137 if (!isset($option_actual[$option[0]])) {
1138 $option_actual[$option[0]] = '';
1139 }
1140
1141 // Add our custom core_terms_promo type
1142 if ($option[2] == 'core_terms_promo') {
1143 if (isset($option[4]) && !empty($option[4])) {
1144 $output .= '<tr style="vertical-align: middle;" class="' . $class . '"><td class="helper" ' . $colspan . '>' . apply_filters('taxopress_admin_manage_' . $option[0], $option[4]) . '</td></tr>' . PHP_EOL;
1145 }
1146 continue;
1147 }
1148
1149 $input_type = '';
1150 $desc_html_tag = 'div';
1151 switch ($option[2]) {
1152 case 'radio':
1153 $input_type = array();
1154 foreach ($option[3] as $value => $text) {
1155 $input_type[] = '<label><input type="radio" id="' . $option[0] . '" name="' . $option[0] . '" value="' . esc_attr($value) . '" ' . checked($value, $option_actual[$option[0]], false) . ' /> ' . $text . '</label>' . PHP_EOL;
1156 }
1157 $input_type = implode('<br />', $input_type);
1158 break;
1159
1160 case 'checkbox':
1161 $desc_html_tag = 'span';
1162 $input_type = '<input type="checkbox" id="' . $option[0] . '" name="' . $option[0] . '" value="' . esc_attr($option[3]) . '" ' . (($option_actual[$option[0]]) ? 'checked="checked"' : '') . ' />' . PHP_EOL;
1163 break;
1164
1165 case 'multiselect':
1166 $desc_html_tag = 'div';
1167 $input_type = array();
1168 foreach ($option[3] as $field_name => $text) {
1169 $selected_option = (is_array($option_actual[$option[0]]) && in_array($field_name, $option_actual[$option[0]])) ? true : false;
1170 $input_type[] = '<label><input type="checkbox" id="' . $option[0] . '-' . $field_name . '" name="' . $option[0] . '[]" value="' . $field_name . '" ' . checked($selected_option, true, false) . ' /> ' . $text . '</label> <br />' . PHP_EOL;
1171 }
1172 $input_type = implode('<br />', $input_type);
1173 break;
1174
1175 case 'sub_multiple_checkbox':
1176 $desc_html_tag = 'div';
1177 $input_type = array();
1178 foreach ($option[3] as $field_name => $field_option) {
1179 $checked_option = !empty($option_actual[$field_name]) ? (int) $option_actual[$field_name] : 0;
1180 $selected_option = ($checked_option > 0) ? true : false;
1181 $field_description = !empty($field_option['description']) ? '<br /><span class="description stpexplan">' . $field_option['description'] . '</span>' : '';
1182 $input_type[] = '<label><input type="checkbox" id="' . $option[0] . '" name="' . $field_name . '" value="1" ' . checked($selected_option, true, false) . ' /> ' . $field_option['label'] . '</label> '. $field_description .'<br />' . PHP_EOL;
1183 }
1184 $input_type = implode('<br />', $input_type);
1185 break;
1186
1187 case 'dropdown':// legacy
1188 $selopts = explode('/', $option[3]);
1189 $seldata = '';
1190 foreach ((array) $selopts as $sel) {
1191 $seldata .= '<option value="' . esc_attr($sel) . '" ' . ((isset($option_actual[$option[0]]) && $option_actual[$option[0]] == $sel) ? 'selected="selected"' : '') . ' >' . ucfirst($sel) . '</option>' . PHP_EOL;
1192 }
1193 $input_type = '<select id="' . $option[0] . '" name="' . $option[0] . '">' . $seldata . '</select>' . PHP_EOL;
1194 break;
1195
1196
1197 case 'select':
1198 $selopts = $option[3];
1199 $seldata = '';
1200 foreach ((array) $selopts as $sel_key => $sel_label) {
1201 $seldata .= '<option value="' . esc_attr($sel_key) . '" ' . ((isset($option_actual[$option[0]]) && $option_actual[$option[0]] == $sel_key) ? 'selected="selected"' : '') . ' >' . ucfirst($sel_label) . '</option>' . PHP_EOL;
1202 }
1203 $input_type = '<select id="' . $option[0] . '" name="' . $option[0] . '">' . $seldata . '</select>' . PHP_EOL;
1204 break;
1205
1206 case 'select_with_icon':
1207 $selopts = $option[3];
1208 $seldata = '';
1209 foreach ((array) $selopts as $sel_key => $sel_label) {
1210 $seldata .= '<option value="' . esc_attr($sel_key) . '" ' . ((isset($option_actual[$option[0]]) && $option_actual[$option[0]] == $sel_key) ? 'selected="selected"' : '') . ' >' . ucfirst($sel_label) . '</option>' . PHP_EOL;
1211 }
1212
1213 $icon_class = isset($option[6]['icon']) ? $option[6]['icon'] : 'dashicons-lock';
1214 $modal_content = isset($option[6]['modal']) ? $option[6]['modal'] : '';
1215 $disabled = !empty($option[8]) && isset($option[8]['disabled']) ? 'disabled="disabled"' : '';
1216 $class_attr = isset($option[5]) ? esc_attr($option[5]) : '';
1217 $icon_wrapper_class = isset($option[6]['icon_wrapper_class']) ? esc_attr($option[6]['icon_wrapper_class']) : 'taxopress-select-icon';
1218 $modal_wrapper_class = isset($option[6]['modal_wrapper_class']) ? esc_attr($option[6]['modal_wrapper_class']) : 'taxopress-select-icon-modal';
1219
1220 $input_type = '<div class="' . $class_attr . '">
1221 <select id="' . $option[0] . '" name="' . $option[0] . '" ' . $disabled . '>' . $seldata . '</select>
1222 <span class="' . $icon_wrapper_class . ' dashicons ' . esc_attr($icon_class) . '">
1223 <div class="' . $modal_wrapper_class . '">' . $modal_content . '</div>
1224 </span>
1225 </div>' . PHP_EOL;
1226 break;
1227
1228 case 'multiselect_with_desc_top':
1229 $desc_html_tag = 'div';
1230 $input_type_array = array();
1231 $prefix = !empty($field_description) ? '<' . $desc_html_tag . ' class="stpexplan">' . $field_description . '</' . $desc_html_tag . '>' : '';
1232 foreach ($field_options as $option_key => $option_label) {
1233 $field_value = isset($option_actual[$field_id]) ? $option_actual[$field_id] : array();
1234 $selected_option = (is_array($field_value) && in_array($option_key, $field_value)) ? true : false;
1235 $input_type_array[] = '<label><input type="checkbox" id="' . esc_attr($field_id . '-' . $option_key) . '" name="' . esc_attr($field_id) . '[]" value="' . esc_attr($option_key) . '" ' . checked($selected_option, true, false) . ' /> ' . esc_html($option_label) . '</label><br />';
1236 }
1237 $input_type = $prefix . implode('', $input_type_array);
1238 $field_description = '';
1239 break;
1240
1241 case 'text-color':
1242 $input_type = '<input type="text" id="' . $option[0] . '" name="' . $option[0] . '" value="' . esc_attr($option_actual[$option[0]]) . '" class="text-color ' . $option[3] . '" />' . PHP_EOL;
1243 break;
1244
1245 case 'text':
1246 $input_type = '<input type="text" id="' . $option[0] . '" name="' . $option[0] . '" value="' . esc_attr($option_actual[$option[0]]) . '" class="' . $option[3] . '" />' . PHP_EOL;
1247 break;
1248
1249 case 'licence_field':
1250 $input_type = '<input type="text" id="' . $option[0] . '" name="' . $option[0] . '" value="' . esc_attr($option[3]) . '" class="' . $option[5] . '" />' . PHP_EOL;
1251 break;
1252
1253 case 'number':
1254 $min_attr = isset($option[6]) ? ' min="' . esc_attr($option[6]) . '"' : '';
1255 $input_type = '<input type="number" id="' . $option[0] . '" name="' . $option[0] . '" value="' . esc_attr($option_actual[$option[0]]) . '" class="' . $option[3] . '"' . $min_attr . ' />' . PHP_EOL;
1256 break;
1257
1258 case 'textarea':
1259 $rows_attr = isset($option[7]['rows']) ? ' rows="' . esc_attr($option[7]['rows']) . '"' : ' rows="4"';
1260 $placeholder_attr = isset($option[7]['placeholder']) ? ' placeholder="' . esc_attr($option[7]['placeholder']) . '"' : '';
1261 $width_attr = (!empty($option[7]['width'])) ? ' style="width:' . esc_attr($option[7]['width']) . ';"' : ' style="width:100%; max-width:600px;"';
1262 $input_type = '<textarea id="' . $option[0] . '" name="' . $option[0] . '"' . $rows_attr . $placeholder_attr . $width_attr . ' class="' . $option[3] . '">' . esc_textarea($option_actual[$option[0]]) . '</textarea>' . PHP_EOL;
1263 break;
1264 }
1265
1266 if (is_array($option[2])) {
1267 $input_type = '<input type="' . $option[2]["type"] . '" id="' . $option[0] . '" name="' . $option[0] . '" value="' . esc_attr($option_actual[$option[0]]) . '" class="' . $option[3] . '" ' . $option[2]["attr"] . ' />' . PHP_EOL;
1268 }
1269
1270 // Additional Information
1271 $extra_prefix = '';
1272 $extra_suffix = '';
1273 if (!empty($option[4])) {
1274 if ($option[2] == 'sub_multiple_checkbox') {
1275 $extra_prefix = '<' . $desc_html_tag . ' class="stpexplan">' . $option[4] . '</' . $desc_html_tag . '>' . PHP_EOL;
1276 } else {
1277 $extra_suffix = '<' . $desc_html_tag . ' class="stpexplan">' . $option[4] . '</' . $desc_html_tag . '>' . PHP_EOL;
1278 }
1279 }
1280
1281 // Output
1282 $output .= '<tr style="vertical-align: top;" class="' . $class . '"><th scope="row"><label for="' . $option[0] . '">' . $option[1] . '</label></th><td>'. $extra_prefix .' ' . $input_type . ' ' . $extra_suffix . '</td></tr>' . PHP_EOL;
1283 }
1284 $output .= '</table>' . PHP_EOL;
1285 $output .= '</fieldset>' . PHP_EOL;
1286 $output .= '</div>' . PHP_EOL;
1287 }
1288
1289 return $output;
1290 }
1291
1292 /**
1293 * Get nice title for tabs title option
1294 *
1295 * @param string $id
1296 *
1297 * @return string
1298 */
1299 public static function getNiceTitleOptions($id = '')
1300 {
1301 switch ($id) {
1302 case 'administration':
1303 return esc_html__('Administration', 'simple-tags');
1304 case 'auto-links':
1305 return esc_html__('Auto link', 'simple-tags');
1306 case 'features':
1307 return esc_html__('Features', 'simple-tags');
1308 case 'embeddedtags':
1309 return esc_html__('Embedded Tags', 'simple-tags');
1310 case 'tagspost':
1311 return esc_html__('Tags for Current Post', 'simple-tags');
1312 case 'relatedposts':
1313 return esc_html__('Related Posts', 'simple-tags');
1314 case 'legacy':
1315 return esc_html__('Legacy', 'simple-tags');
1316 case 'posts':
1317 return esc_html__('Posts', 'simple-tags');
1318 case 'taxopress-ai':
1319 return esc_html__('Metaboxes', 'simple-tags');
1320 case 'metabox':
1321 return esc_html__('Metabox Access', 'simple-tags');
1322 case 'linked_terms':
1323 return esc_html__('Linked Terms', 'simple-tags');
1324 case 'synonyms':
1325 return esc_html__('Term Synonyms', 'simple-tags');
1326 case 'licence':
1327 return esc_html__('License', 'simple-tags');
1328 case 'hidden_terms':
1329 return esc_html__('Hidden Terms', 'simple-tags');
1330 case 'manage_terms':
1331 return esc_html__('Manage Terms', 'simple-tags');
1332 case 'mass_edit_terms':
1333 return esc_html__('Mass Edit Terms', 'simple-tags');
1334 case 'core_linked_terms':
1335 return esc_html__('Linked Terms', 'simple-tags');
1336 case 'core_synonyms_terms':
1337 return esc_html__('Term Synonyms', 'simple-tags');
1338 case 'legacy_ai_sources':
1339 return esc_html__('Auto Terms', 'simple-tags');
1340 }
1341
1342 return '';
1343 }
1344
1345 /**
1346 * This method allow to check if the DB is up to date, and if a upgrade is need for options
1347 * TODO, useful or delete ?
1348 *
1349 * @return void
1350 * @author WebFactory Ltd
1351 */
1352 public static function upgrade()
1353 {
1354 // Get current version number
1355 $current_version = get_option(STAGS_OPTIONS_NAME . '-version');
1356
1357 // Upgrade needed ?
1358 if ($current_version == false || version_compare($current_version, STAGS_VERSION, '<')) {
1359 $current_options = get_option(STAGS_OPTIONS_NAME);
1360 $default_options = (array) include(STAGS_DIR . '/inc/helper.options.default.php');
1361
1362 // Add new options
1363 foreach ($default_options as $key => $default_value) {
1364 if (!isset($current_options[$key])) {
1365 $current_options[$key] = $default_value;
1366 }
1367 }
1368
1369 // Remove old options
1370 /*foreach ($current_options as $key => $current_value) {
1371 if (!isset($default_options[$key])) {
1372 unset($current_options[$key]);
1373 }
1374 }*/
1375
1376 update_option(STAGS_OPTIONS_NAME . '-version', STAGS_VERSION);
1377 update_option(STAGS_OPTIONS_NAME, $current_options);
1378 }
1379 }
1380
1381 /**
1382 * Make a simple SQL query with some args for get terms for ajax display
1383 *
1384 * @param string $taxonomy
1385 * @param string $search
1386 * @param string $order_by
1387 * @param string $order
1388 *
1389 * @return array
1390 * @author WebFactory Ltd
1391 */
1392 public static function getTermsForAjax($taxonomy = 'post_tag', $search = '', $order_by = 'name', $order = 'ASC', $limit = 0)
1393 {
1394 global $wpdb;
1395
1396 $order = strtoupper($order);
1397 if (!in_array($order, ['ASC', 'DESC'], true)) {
1398 $order = 'ASC';
1399 }
1400
1401 $allowed_orderby = [
1402 'name' => 't.name',
1403 'count' => 'tt.count',
1404 'random' => 'RAND()',
1405 ];
1406
1407 if (isset($allowed_orderby[$order_by])) {
1408 $order_by_sql = $allowed_orderby[$order_by];
1409 } else {
1410 $order_by_sql = $allowed_orderby['name'];
1411 }
1412
1413 $limit_sql = '';
1414 $limit = (int) $limit;
1415 if ($limit > 0) {
1416 $limit_sql = $wpdb->prepare('LIMIT 0, %d', $limit);
1417 }
1418
1419 if ($taxonomy == 'linked_term_taxonomies') {
1420 $taxonomies = SimpleTags_Plugin::get_option_value('linked_terms_taxonomies');
1421 if (empty($taxonomies) || !is_array($taxonomies)) {
1422 $taxonomies = ['category', 'post_tag'];
1423 }
1424 $taxonomies_list = "'" . implode("', '", $taxonomies) . "'";
1425 }
1426
1427 if (!empty($search)) {
1428 if ($taxonomy == 'linked_term_taxonomies') {
1429
1430 $query = $wpdb->prepare("
1431 SELECT DISTINCT t.name, t.term_id, tt.taxonomy
1432 FROM {$wpdb->terms} AS t
1433 INNER JOIN {$wpdb->term_taxonomy} AS tt ON t.term_id = tt.term_id
1434 WHERE tt.taxonomy IN ($taxonomies_list)
1435 AND t.name LIKE %s
1436 ORDER BY $order_by_sql $order $limit_sql
1437 ", '%' . $wpdb->esc_like($search) . '%'
1438 );
1439 } else {
1440 $query = $wpdb->prepare("
1441 SELECT DISTINCT t.name, t.slug, t.term_id, tt.taxonomy
1442 FROM {$wpdb->terms} AS t
1443 INNER JOIN {$wpdb->term_taxonomy} AS tt ON t.term_id = tt.term_id
1444 WHERE tt.taxonomy = %s
1445 AND t.name LIKE %s
1446 ORDER BY $order_by_sql $order $limit_sql
1447 ", $taxonomy, '%' . $wpdb->esc_like($search) . '%'
1448 );
1449 }
1450 return $wpdb->get_results($query);
1451 } else {
1452 if ($taxonomy == 'linked_term_taxonomies') {
1453 $query = "
1454 SELECT DISTINCT t.name, t.term_id, tt.taxonomy
1455 FROM {$wpdb->terms} AS t
1456 INNER JOIN {$wpdb->term_taxonomy} AS tt ON t.term_id = tt.term_id
1457 WHERE tt.taxonomy IN ($taxonomies_list)
1458 ORDER BY $order_by_sql $order $limit_sql
1459 ";
1460
1461 } else {
1462 $query = $wpdb->prepare("
1463 SELECT DISTINCT t.name, t.slug, t.term_id, tt.taxonomy
1464 FROM {$wpdb->terms} AS t
1465 INNER JOIN {$wpdb->term_taxonomy} AS tt ON t.term_id = tt.term_id
1466 WHERE tt.taxonomy = %s
1467 ORDER BY $order_by_sql $order $limit_sql
1468 ", $taxonomy);
1469 }
1470
1471 return $wpdb->get_results($query);
1472 }
1473 }
1474
1475 /**
1476 * Plugin installer/uograde code
1477 *
1478 * @return void
1479 */
1480 public static function plugin_installer_upgrade_code()
1481 {
1482 if (!get_option('taxopress_3_23_0_upgrade_completed')) {
1483
1484 $options = SimpleTags_Plugin::get_option();
1485
1486 // add metabox default values
1487 $tax_names = array_keys(get_taxonomies([], 'names'));
1488 foreach (taxopress_get_all_wp_roles() as $role_name => $role_info) {
1489 if (in_array($role_name, ['administrator', 'editor', 'author', 'contributor'])) {
1490 $enable_acess_default_value = 1;
1491 } else {
1492 $enable_acess_default_value = 0;
1493 }
1494 $options['enable_' . $role_name . '_metabox'] = $enable_acess_default_value;
1495 $options['enable_metabox_' . $role_name . ''] = $tax_names;
1496 $options['remove_taxonomy_metabox_' . $role_name . ''] = [];
1497 }
1498
1499 SimpleTags_Plugin::set_option($options);
1500
1501 update_option('taxopress_3_23_0_upgrade_completed', true);
1502 } elseif (!get_option('taxopress_3_28_0_upgrade_completed')) {
1503
1504 if (function_exists('taxopress_get_autoterm_data')) {
1505 $autoterms = taxopress_get_autoterm_data();
1506 foreach ($autoterms as $autoterm_index => $autoterm) {
1507 //enable when to fields
1508 $autoterms[$autoterm_index]['autoterm_for_post'] = 1;
1509 $autoterms[$autoterm_index]['autoterm_for_schedule'] = 1;
1510 $autoterms[$autoterm_index]['autoterm_for_existing_content'] = 1;
1511 $autoterms[$autoterm_index]['autoterm_for_metaboxes'] = 1;
1512 // update new cloned fields for other groups
1513 $autoterms[$autoterm_index]['schedule_terms_limit'] = !empty($autoterm['terms_limit']) ? $autoterm['terms_limit'] : 5;
1514 $autoterms[$autoterm_index]['schedule_autoterm_target'] = !empty($autoterm['autoterm_target']) ? $autoterm['autoterm_target'] : 0;
1515 $autoterms[$autoterm_index]['schedule_autoterm_word'] = !empty($autoterm['autoterm_word']) ? $autoterm['autoterm_word'] : 0;
1516 $autoterms[$autoterm_index]['schedule_autoterm_hash'] = !empty($autoterm['autoterm_hash']) ? $autoterm['autoterm_hash'] : 0;
1517
1518 $autoterms[$autoterm_index]['existing_content_terms_limit'] = !empty($autoterm['terms_limit']) ? $autoterm['terms_limit'] : 5;
1519 }
1520 update_option('taxopress_autoterms', $autoterms);
1521 }
1522 update_option('taxopress_3_28_0_upgrade_completed', true);
1523 }
1524 }
1525
1526 /**
1527 * Redirect user on plugin activation
1528 *
1529 * @return void
1530 */
1531 public static function redirect_on_activate()
1532 {
1533 if (get_option('taxopress_activate')) {
1534 delete_option('taxopress_activate');
1535 wp_redirect(admin_url("admin.php?page=st_dashboard&welcome"));
1536 exit;
1537 }
1538 }
1539 }
1540