PluginProbe
Tag, Category, and Taxonomy Manager – Autotagger Automatically Add Terms / 3.38.0
Tag, Category, and Taxonomy Manager – Autotagger Automatically Add Terms v3.38.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.38.0, at inc/class.admin.php

1,446 lines 53.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'])) || 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 'select_post_label' => esc_html__('Search Posts...', 'simple-tags'),
743 'loading' => esc_html__('Loading...', 'simple-tags'),
744 'preview_error' => esc_html__('Error loading preview', 'simple-tags'),
745 'enable_ibm_watson_ai_source' => SimpleTags_Plugin::get_option_value('enable_ibm_watson_ai_source'),
746 'enable_dandelion_ai_source' => SimpleTags_Plugin::get_option_value('enable_dandelion_ai_source'),
747 'enable_lseg_ai_source' => SimpleTags_Plugin::get_option_value('enable_lseg_ai_source'),
748 'plugin_url' => STAGS_URL,
749 'using_default_text' => __('Using default TaxoPress image', 'simple-tags'),
750 'select_image_label' => esc_html__('Select Media', 'simple-tags'),
751 'change_image_label' => esc_html__('Change Media', 'simple-tags'),
752 'use_default_label' => esc_html__('Use Default', 'simple-tags'),
753 ]);
754
755
756 //Register remodal assets
757 wp_register_script('st-remodal-js', STAGS_URL . '/assets/js/remodal.min.js', array('jquery'), STAGS_VERSION);
758 wp_register_style('st-remodal-css', STAGS_URL . '/assets/css/remodal.css', array(), STAGS_VERSION, 'all');
759 wp_register_style('st-remodal-default-theme-css', STAGS_URL . '/assets/css/remodal-default-theme.css', array(), STAGS_VERSION, 'all');
760
761 // Register location
762 $wp_post_pages = array('post.php', 'post-new.php');
763 $wp_page_pages = array('page.php', 'page-new.php');
764
765 wp_enqueue_style('st-admin-global');
766
767 // Common Helper for Post, Page and Plugin Page
768 if (
769 in_array($pagenow, $wp_post_pages) ||
770 (in_array($pagenow, $wp_page_pages) && is_page_have_tags()) ||
771 (isset($_GET['page']) && in_array($_GET['page'], $taxopress_pages))
772 ) {
773 wp_enqueue_script('st-remodal-js');
774 wp_enqueue_style('st-remodal-css');
775 wp_enqueue_style('st-remodal-default-theme-css');
776 wp_enqueue_style('st-admin');
777
778 do_action('taxopress_admin_class_after_styles_enqueue');
779 }
780
781 // add jQuery tabs for options page. Use jQuery UI Tabs from WP
782 if (isset($_GET['page']) && in_array($_GET['page'], array('st_options', 'st_terms_display', 'st_post_tags', 'st_related_posts',))) {
783 wp_enqueue_script('jquery-ui-tabs');
784 wp_enqueue_script('st-helper-options');
785 }
786
787 do_action('taxopress_admin_class_after_assets_enqueue');
788 }
789
790 /**
791 * Add settings page on WordPress admin menu
792 *
793 * @return void
794 * @author WebFactory Ltd
795 */
796 public static function admin_menu()
797 {
798 self::$admin_url = admin_url('admin.php?page=' . self::MENU_SLUG);
799
800 add_menu_page(
801 __('TaxoPress: Options', 'simple-tags'),
802 __('TaxoPress', 'simple-tags'),
803 'admin_simple_tags',
804 self::MENU_SLUG,
805 array(
806 __CLASS__,
807 'page_options',
808 ),
809 'dashicons-tag',
810 69
811 );
812 add_submenu_page(
813 self::MENU_SLUG,
814 __('TaxoPress: Options', 'simple-tags'),
815 __('Settings', 'simple-tags'),
816 'admin_simple_tags',
817 self::MENU_SLUG,
818 array(
819 __CLASS__,
820 'page_options',
821 )
822 );
823 }
824
825 /**
826 * Build HTML for page options, manage also save/reset settings
827 *
828 * @return void
829 * @author WebFactory Ltd
830 */
831 public static function page_options()
832 {
833 // Get options
834 $options = (array) SimpleTags_Plugin::get_option();
835
836 if (current_user_can('admin_simple_tags')) {
837 // Update or reset options
838 if (isset($_POST['updateoptions'])) {
839 $dashboard_options = taxopress_dashboard_options();
840 $dashboard_option_keys = array_column($dashboard_options, 'option_key');
841
842 check_admin_referer('updateresetoptions-simpletags');
843
844 $sanitized_options = [];
845
846 // add taxopress ai post type and taxonomies options so we can have all post types. TODO: This need to be a filter
847 foreach (get_post_types(['public' => true], 'names') as $post_type => $post_type_object) {
848 if ($post_type == 'post') {
849 $opt_default_value = 'post_tag';
850 } else {
851 $opt_default_value = 0;
852 }
853 $options['taxopress_ai_' . $post_type . '_metabox_default_taxonomy'] = $opt_default_value;
854 $options['taxopress_ai_' . $post_type . '_metabox_display_option'] = 'default';
855 $options['taxopress_ai_' . $post_type . '_support_private_taxonomy'] = 0;
856
857 $options['taxopress_ai_' . $post_type . '_metabox_orderby'] = 'count';
858 $options['taxopress_ai_' . $post_type . '_metabox_order'] = 'desc';
859 $options['taxopress_ai_' . $post_type . '_metabox_maximum_terms'] = 45;
860 $options['taxopress_ai_' . $post_type . '_metabox_show_post_count'] = 0;
861
862 $options['taxopress_ai_' . $post_type . '_minimum_term_length'] = 2;
863 $options['taxopress_ai_' . $post_type . '_maximum_term_length'] = 40;
864
865
866 $options['taxopress_ai_' . $post_type . '_exclusions'] = '';
867 $options['enable_taxopress_ai_' . $post_type . '_metabox'] = $opt_default_value;
868 $options['taxopress_ai_' . $post_type . '_metabox_filters'] = 1;
869 foreach (['post_terms', 'existing_terms', 'suggest_local_terms', 'create_terms'] as $taxopress_ai_tab) {
870 $options['enable_taxopress_ai_' . $post_type . '_' . $taxopress_ai_tab . '_tab'] = $opt_default_value;
871 }
872 }
873
874 // add metabox post type and taxonomies options so we can have all post types. TODO: This need to be a filter
875 foreach (taxopress_get_all_wp_roles() as $role_name => $role_info) {
876 if (in_array($role_name, ['administrator', 'editor', 'author', 'contributor'])) {
877 $enable_acess_default_value = 1;
878 } else {
879 $enable_acess_default_value = 0;
880 }
881 $options['enable_' . $role_name . '_metabox'] = $enable_acess_default_value;
882 $options['enable_restrict' . $role_name . '_metabox'] = $enable_acess_default_value;
883
884 // ONLY admin + editor default to can edit
885 if (!isset($options['enable_edit_' . $role_name . '_metabox'])) {
886 $options['enable_edit_' . $role_name . '_metabox'] = in_array($role_name, ['administrator', 'editor']) ? 1 : 0;
887 }
888
889 $options['enable_metabox_' . $role_name . ''] = [];
890 $options['remove_taxonomy_metabox_' . $role_name . ''] = [];
891 }
892
893 foreach ($options as $key => $value) {
894 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
895 $value = isset($_POST[$key]) ? $_POST[$key] : '';
896
897 if (empty($value) && in_array($key, $dashboard_option_keys)) {
898 $value = SimpleTags_Plugin::get_option_value($key);
899 }
900
901 if (!is_array($value)) {
902 $sanitized_options[$key] = taxopress_sanitize_text_field($value);
903 } else {
904 $sanitized_options[$key] = map_deep($value, 'sanitize_text_field');
905 }
906 }
907 $options = $sanitized_options;
908
909 SimpleTags_Plugin::set_option($options);
910
911 do_action('simpletags_settings_save_general_end');
912 do_action('taxopress_settings_saved');
913
914 add_settings_error(__CLASS__, __CLASS__, esc_html__('Options saved', 'simple-tags'), 'updated taxopress-notice');
915 } elseif (isset($_POST['reset_options'])) {
916 check_admin_referer('updateresetoptions-simpletags');
917
918 SimpleTags_Plugin::set_default_option();
919
920 add_settings_error(__CLASS__, __CLASS__, esc_html__('TaxoPress options resetted to default options!', 'simple-tags'), 'updated taxopress-notice');
921 } else {
922 //add_settings_error(__CLASS__, __CLASS__, esc_html__('Settings updated', 'simple-tags'), 'updated');
923 }
924 }
925
926 settings_errors(__CLASS__);
927 include STAGS_DIR . '/views/admin/page-settings.php';
928 }
929
930 /**
931 * Get terms for a post, format terms for input and autocomplete usage
932 *
933 * @param string $taxonomy
934 * @param integer $post_id
935 *
936 * @return string
937 * @author WebFactory Ltd
938 */
939 public static function getTermsToEdit($taxonomy = 'post_tag', $post_id = 0)
940 {
941 $post_id = (int) $post_id;
942 if (!$post_id) {
943 return '';
944 }
945
946 $terms = wp_get_post_terms($post_id, $taxonomy, array('fields' => 'names'));
947 if (empty($terms) || is_wp_error($terms)) {
948 return '';
949 }
950
951 $terms = array_unique($terms); // Remove duplicate
952 $terms = join(', ', $terms);
953 $terms = esc_attr($terms);
954 $terms = apply_filters('tags_to_edit', $terms);
955
956 return $terms;
957 }
958
959 /**
960 * Default content for meta box of TaxoPress
961 *
962 * @return string
963 * @author WebFactory Ltd
964 */
965 public static function getDefaultContentBox()
966 {
967 if ((int) wp_count_terms('post_tag', array('hide_empty' => false)) == 0) { // TODO: Custom taxonomy
968 return esc_html__('This feature requires at least 1 tag to work. Begin by adding tags!', 'simple-tags');
969 } else {
970 return esc_html__('This feature works only with activated JavaScript. Activate it in your Web browser so you can!', 'simple-tags');
971 }
972 }
973
974 /**
975 * A short public static function for display the same copyright on all admin pages
976 *
977 * @return void
978 * @author WebFactory Ltd
979 */
980 public static function printAdminFooter()
981 {
982 /* ?>
983 <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>
984 <?php */
985 }
986
987 /**
988 * A short public static function for display the same copyright on all taxopress admin pages
989 *
990 * @return void
991 * @author Olatechpro
992 */
993 public static function taxopress_admin_footer()
994 {
995
996 $taxopress_pages = taxopress_admin_pages();
997
998 if (isset($_GET['page']) && in_array($_GET['page'], $taxopress_pages)) {
999 ?>
1000 <p class="footer_st">
1001 <?php
1002 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1003 printf(__('Thanks for using TaxoPress | %1sTaxoPress.com%2s | Version %3s', 'simple-tags'), '<a href="https://taxopress.com/">', '</a>', esc_html(STAGS_VERSION)); ?>
1004 </p>
1005 <?php
1006 }
1007 }
1008
1009 /**
1010 * Ouput formatted options
1011 *
1012 * @param array $option_data
1013 *
1014 * @return string
1015 * @author WebFactory Ltd
1016 */
1017 public static function print_options($option_data)
1018 {
1019 // Get options
1020 $option_actual = SimpleTags_Plugin::get_option();
1021
1022 // Generate output
1023 $output = '';
1024 foreach ($option_data as $section => $options) {
1025 $colspan = count($options) > 1 ? 'colspan="2"' : '';
1026
1027 if ($section === 'legacy') {
1028 $table_sub_tab = '<div class="st-legacy-subtab">
1029 <span class="active" data-content=".legacy-tag-cloud-content">'. esc_html__("Tag Cloud", "simple-tags") .'</span> |
1030 <span data-content=".legacy-post-tags-content">'. esc_html__("Tags for Current Post", "simple-tags") .'</span> |
1031 <span data-content=".legacy-related-posts-content">'. esc_html__("Related Posts", "simple-tags") .'</span> |
1032 <span data-content=".legacy-auto-link-content">'. esc_html__("Auto Links", "simple-tags") .'</span>
1033 </div>' . PHP_EOL;
1034 } elseif ($section === 'taxopress-ai') {
1035 $table_sub_tab_lists = [];
1036 $pt_index = 0;
1037 foreach (TaxoPressAiUtilities::get_post_types_options() as $post_type => $post_type_object) {
1038
1039 if (!in_array($post_type, ['attachment'])) {
1040 $active_pt = ($pt_index === 0) ? 'active' : '';
1041 $table_sub_tab_lists[] = '<span class="' . $active_pt . '" data-content=".taxopress-ai-' . $post_type . '-content">' . esc_html($post_type_object->labels->name) . '</span>';
1042 $pt_index++;
1043 }
1044 }
1045 $table_sub_tab = '<div class="st-taxopress-ai-subtab">' . join(' | ', $table_sub_tab_lists). '</div>' . PHP_EOL;
1046 } elseif ($section === 'metabox') {
1047 $table_sub_tab_lists = [];
1048 $pt_index = 0;
1049 foreach (taxopress_get_all_wp_roles() as $role_name => $role_info) {
1050 $active_pt = ($pt_index === 0) ? 'active' : '';
1051 $table_sub_tab_lists[] = '<span class="' . $active_pt . '" data-content=".metabox-' . $role_name . '-content">' . esc_html(translate_user_role($role_info['name'])) . '</span>';
1052 $pt_index++;
1053 }
1054 $table_sub_tab = '<div class="st-metabox-subtab">' . join(' | ', $table_sub_tab_lists). '</div>' . PHP_EOL;
1055 } else {
1056 $table_sub_tab = '';
1057 }
1058
1059 $output .= '<div class="group" id="' . sanitize_title($section) . '">' . PHP_EOL;
1060 $output .= $table_sub_tab;
1061 $output .= '<fieldset class="options">' . PHP_EOL;
1062 $output .= '<legend>' . self::getNiceTitleOptions($section) . '</legend>' . PHP_EOL;
1063 $output .= '<table class="form-table">' . PHP_EOL;
1064 foreach ((array) $options as $option) {
1065
1066 $class = '';
1067 if (in_array($section, ['legacy', 'taxopress-ai', 'metabox'])) {
1068 $class = $option[5];
1069 }
1070
1071 // Helper
1072 if ($option[2] == 'helper') {
1073 $output .= '<tr style="vertical-align: middle;" class="' . $class . '"><td class="helper stpexplan" ' . $colspan . '>' . stripslashes($option[4]) . '</td></tr>' . PHP_EOL;
1074 continue;
1075 }
1076
1077 // Fix notices
1078 if (!isset($option_actual[$option[0]])) {
1079 $option_actual[$option[0]] = '';
1080 }
1081
1082 // Add our custom core_terms_promo type
1083 if ($option[2] == 'core_terms_promo') {
1084 if (isset($option[4]) && !empty($option[4])) {
1085 $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;
1086 }
1087 continue;
1088 }
1089
1090 $input_type = '';
1091 $desc_html_tag = 'div';
1092 switch ($option[2]) {
1093 case 'radio':
1094 $input_type = array();
1095 foreach ($option[3] as $value => $text) {
1096 $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;
1097 }
1098 $input_type = implode('<br />', $input_type);
1099 break;
1100
1101 case 'checkbox':
1102 $desc_html_tag = 'span';
1103 $input_type = '<input type="checkbox" id="' . $option[0] . '" name="' . $option[0] . '" value="' . esc_attr($option[3]) . '" ' . (($option_actual[$option[0]]) ? 'checked="checked"' : '') . ' />' . PHP_EOL;
1104 break;
1105
1106 case 'multiselect':
1107 $desc_html_tag = 'div';
1108 $input_type = array();
1109 foreach ($option[3] as $field_name => $text) {
1110 $selected_option = (is_array($option_actual[$option[0]]) && in_array($field_name, $option_actual[$option[0]])) ? true : false;
1111 $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;
1112 }
1113 $input_type = implode('<br />', $input_type);
1114 break;
1115
1116 case 'sub_multiple_checkbox':
1117 $desc_html_tag = 'div';
1118 $input_type = array();
1119 foreach ($option[3] as $field_name => $field_option) {
1120 $checked_option = !empty($option_actual[$field_name]) ? (int) $option_actual[$field_name] : 0;
1121 $selected_option = ($checked_option > 0) ? true : false;
1122 $field_description = !empty($field_option['description']) ? '<br /><span class="description stpexplan">' . $field_option['description'] . '</span>' : '';
1123 $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;
1124 }
1125 $input_type = implode('<br />', $input_type);
1126 break;
1127
1128 case 'dropdown':// legacy
1129 $selopts = explode('/', $option[3]);
1130 $seldata = '';
1131 foreach ((array) $selopts as $sel) {
1132 $seldata .= '<option value="' . esc_attr($sel) . '" ' . ((isset($option_actual[$option[0]]) && $option_actual[$option[0]] == $sel) ? 'selected="selected"' : '') . ' >' . ucfirst($sel) . '</option>' . PHP_EOL;
1133 }
1134 $input_type = '<select id="' . $option[0] . '" name="' . $option[0] . '">' . $seldata . '</select>' . PHP_EOL;
1135 break;
1136
1137
1138 case 'select':
1139 $selopts = $option[3];
1140 $seldata = '';
1141 foreach ((array) $selopts as $sel_key => $sel_label) {
1142 $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;
1143 }
1144 $input_type = '<select id="' . $option[0] . '" name="' . $option[0] . '">' . $seldata . '</select>' . PHP_EOL;
1145 break;
1146
1147 case 'select_with_icon':
1148 $selopts = $option[3];
1149 $seldata = '';
1150 foreach ((array) $selopts as $sel_key => $sel_label) {
1151 $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;
1152 }
1153
1154 $icon_class = isset($option[6]['icon']) ? $option[6]['icon'] : 'dashicons-lock';
1155 $modal_content = isset($option[6]['modal']) ? $option[6]['modal'] : '';
1156 $disabled = !empty($option[8]) && isset($option[8]['disabled']) ? 'disabled="disabled"' : '';
1157 $class_attr = isset($option[5]) ? esc_attr($option[5]) : '';
1158 $icon_wrapper_class = isset($option[6]['icon_wrapper_class']) ? esc_attr($option[6]['icon_wrapper_class']) : 'taxopress-select-icon';
1159 $modal_wrapper_class = isset($option[6]['modal_wrapper_class']) ? esc_attr($option[6]['modal_wrapper_class']) : 'taxopress-select-icon-modal';
1160
1161 $input_type = '<div class="' . $class_attr . '">
1162 <select id="' . $option[0] . '" name="' . $option[0] . '" ' . $disabled . '>' . $seldata . '</select>
1163 <span class="' . $icon_wrapper_class . ' dashicons ' . esc_attr($icon_class) . '">
1164 <div class="' . $modal_wrapper_class . '">' . $modal_content . '</div>
1165 </span>
1166 </div>' . PHP_EOL;
1167 break;
1168
1169 case 'text-color':
1170 $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;
1171 break;
1172
1173 case 'text':
1174 $input_type = '<input type="text" id="' . $option[0] . '" name="' . $option[0] . '" value="' . esc_attr($option_actual[$option[0]]) . '" class="' . $option[3] . '" />' . PHP_EOL;
1175 break;
1176
1177 case 'licence_field':
1178 $input_type = '<input type="text" id="' . $option[0] . '" name="' . $option[0] . '" value="' . esc_attr($option[3]) . '" class="' . $option[5] . '" />' . PHP_EOL;
1179 break;
1180
1181 case 'number':
1182 $min_attr = isset($option[6]) ? ' min="' . esc_attr($option[6]) . '"' : '';
1183 $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;
1184 break;
1185
1186 case 'textarea':
1187 $rows_attr = isset($option[7]['rows']) ? ' rows="' . esc_attr($option[7]['rows']) . '"' : ' rows="4"';
1188 $placeholder_attr = isset($option[7]['placeholder']) ? ' placeholder="' . esc_attr($option[7]['placeholder']) . '"' : '';
1189 $width_attr = (!empty($option[7]['width'])) ? ' style="width:' . esc_attr($option[7]['width']) . ';"' : ' style="width:100%; max-width:600px;"';
1190 $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;
1191 break;
1192 }
1193
1194 if (is_array($option[2])) {
1195 $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;
1196 }
1197
1198 // Additional Information
1199 $extra_prefix = '';
1200 $extra_suffix = '';
1201 if (!empty($option[4])) {
1202 if ($option[2] == 'sub_multiple_checkbox') {
1203 $extra_prefix = '<' . $desc_html_tag . ' class="stpexplan">' . __($option[4]) . '</' . $desc_html_tag . '>' . PHP_EOL;
1204 } else {
1205 $extra_suffix = '<' . $desc_html_tag . ' class="stpexplan">' . __($option[4]) . '</' . $desc_html_tag . '>' . PHP_EOL;
1206 }
1207 }
1208
1209 // Output
1210 $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;
1211 }
1212 $output .= '</table>' . PHP_EOL;
1213 $output .= '</fieldset>' . PHP_EOL;
1214 $output .= '</div>' . PHP_EOL;
1215 }
1216
1217 return $output;
1218 }
1219
1220 /**
1221 * Get nice title for tabs title option
1222 *
1223 * @param string $id
1224 *
1225 * @return string
1226 */
1227 public static function getNiceTitleOptions($id = '')
1228 {
1229 switch ($id) {
1230 case 'administration':
1231 return esc_html__('Administration', 'simple-tags');
1232 case 'auto-links':
1233 return esc_html__('Auto link', 'simple-tags');
1234 case 'features':
1235 return esc_html__('Features', 'simple-tags');
1236 case 'embeddedtags':
1237 return esc_html__('Embedded Tags', 'simple-tags');
1238 case 'tagspost':
1239 return esc_html__('Tags for Current Post', 'simple-tags');
1240 case 'relatedposts':
1241 return esc_html__('Related Posts', 'simple-tags');
1242 case 'legacy':
1243 return esc_html__('Legacy', 'simple-tags');
1244 case 'posts':
1245 return esc_html__('Posts', 'simple-tags');
1246 case 'taxopress-ai':
1247 return esc_html__('Metaboxes', 'simple-tags');
1248 case 'metabox':
1249 return esc_html__('Metabox Access', 'simple-tags');
1250 case 'linked_terms':
1251 return esc_html__('Linked Terms', 'simple-tags');
1252 case 'synonyms':
1253 return esc_html__('Term Synonyms', 'simple-tags');
1254 case 'licence':
1255 return esc_html__('License', 'simple-tags');
1256 case 'hidden_terms':
1257 return esc_html__('Hidden Terms', 'simple-tags');
1258 case 'manage_terms':
1259 return esc_html__('Manage Terms', 'simple-tags');
1260 case 'core_linked_terms':
1261 return esc_html__('Linked Terms', 'simple-tags');
1262 case 'core_synonyms_terms':
1263 return esc_html__('Term Synonyms', 'simple-tags');
1264 case 'legacy_ai_sources':
1265 return esc_html__('Auto Terms', 'simple-tags');
1266 }
1267
1268 return '';
1269 }
1270
1271 /**
1272 * This method allow to check if the DB is up to date, and if a upgrade is need for options
1273 * TODO, useful or delete ?
1274 *
1275 * @return void
1276 * @author WebFactory Ltd
1277 */
1278 public static function upgrade()
1279 {
1280 // Get current version number
1281 $current_version = get_option(STAGS_OPTIONS_NAME . '-version');
1282
1283 // Upgrade needed ?
1284 if ($current_version == false || version_compare($current_version, STAGS_VERSION, '<')) {
1285 $current_options = get_option(STAGS_OPTIONS_NAME);
1286 $default_options = (array) include(STAGS_DIR . '/inc/helper.options.default.php');
1287
1288 // Add new options
1289 foreach ($default_options as $key => $default_value) {
1290 if (!isset($current_options[$key])) {
1291 $current_options[$key] = $default_value;
1292 }
1293 }
1294
1295 // Remove old options
1296 /*foreach ($current_options as $key => $current_value) {
1297 if (!isset($default_options[$key])) {
1298 unset($current_options[$key]);
1299 }
1300 }*/
1301
1302 update_option(STAGS_OPTIONS_NAME . '-version', STAGS_VERSION);
1303 update_option(STAGS_OPTIONS_NAME, $current_options);
1304 }
1305 }
1306
1307 /**
1308 * Make a simple SQL query with some args for get terms for ajax display
1309 *
1310 * @param string $taxonomy
1311 * @param string $search
1312 * @param string $order_by
1313 * @param string $order
1314 *
1315 * @return array
1316 * @author WebFactory Ltd
1317 */
1318 public static function getTermsForAjax($taxonomy = 'post_tag', $search = '', $order_by = 'name', $order = 'ASC', $limit = '')
1319 {
1320 global $wpdb;
1321
1322 if ($order_by === 'random') {
1323 $order_by = 'RAND()';
1324 }
1325 if ($taxonomy == 'linked_term_taxonomies') {
1326 $taxonomies = SimpleTags_Plugin::get_option_value('linked_terms_taxonomies');
1327 if (empty($taxonomies) || !is_array($taxonomies)) {
1328 $taxonomies = ['category', 'post_tag'];
1329 }
1330 $taxonomies_list = "'" . implode("', '", $taxonomies) . "'";
1331 }
1332
1333 if (!empty($search)) {
1334 if ($taxonomy == 'linked_term_taxonomies') {
1335
1336 $query = $wpdb->prepare("
1337 SELECT DISTINCT t.name, t.term_id, tt.taxonomy
1338 FROM {$wpdb->terms} AS t
1339 INNER JOIN {$wpdb->term_taxonomy} AS tt ON t.term_id = tt.term_id
1340 WHERE tt.taxonomy IN ($taxonomies_list)
1341 AND t.name LIKE %s
1342 ORDER BY $order_by $order $limit
1343 ", '%' . $wpdb->esc_like($search) . '%'
1344 );
1345 } else {
1346 $query = $wpdb->prepare("
1347 SELECT DISTINCT t.name, t.term_id, tt.taxonomy
1348 FROM {$wpdb->terms} AS t
1349 INNER JOIN {$wpdb->term_taxonomy} AS tt ON t.term_id = tt.term_id
1350 WHERE tt.taxonomy = %s
1351 AND t.name LIKE %s
1352 ORDER BY $order_by $order $limit
1353 ", $taxonomy, '%' . $wpdb->esc_like($search) . '%'
1354 );
1355 }
1356 return $wpdb->get_results($query);
1357 } else {
1358 if ($taxonomy == 'linked_term_taxonomies') {
1359 $query = "
1360 SELECT DISTINCT t.name, t.term_id, tt.taxonomy
1361 FROM {$wpdb->terms} AS t
1362 INNER JOIN {$wpdb->term_taxonomy} AS tt ON t.term_id = tt.term_id
1363 WHERE tt.taxonomy IN ($taxonomies_list)
1364 ORDER BY $order_by $order $limit
1365 ";
1366
1367 } else {
1368 $query = $wpdb->prepare("
1369 SELECT DISTINCT t.name, t.term_id, tt.taxonomy
1370 FROM {$wpdb->terms} AS t
1371 INNER JOIN {$wpdb->term_taxonomy} AS tt ON t.term_id = tt.term_id
1372 WHERE tt.taxonomy = %s
1373 ORDER BY $order_by $order $limit
1374 ", $taxonomy);
1375 }
1376
1377 return $wpdb->get_results($query);
1378 }
1379 }
1380
1381 /**
1382 * Plugin installer/uograde code
1383 *
1384 * @return void
1385 */
1386 public static function plugin_installer_upgrade_code()
1387 {
1388 if (!get_option('taxopress_3_23_0_upgrade_completed')) {
1389
1390 $options = SimpleTags_Plugin::get_option();
1391
1392 // add metabox default values
1393 $tax_names = array_keys(get_taxonomies([], 'names'));
1394 foreach (taxopress_get_all_wp_roles() as $role_name => $role_info) {
1395 if (in_array($role_name, ['administrator', 'editor', 'author', 'contributor'])) {
1396 $enable_acess_default_value = 1;
1397 } else {
1398 $enable_acess_default_value = 0;
1399 }
1400 $options['enable_' . $role_name . '_metabox'] = $enable_acess_default_value;
1401 $options['enable_metabox_' . $role_name . ''] = $tax_names;
1402 $options['remove_taxonomy_metabox_' . $role_name . ''] = [];
1403 }
1404
1405 SimpleTags_Plugin::set_option($options);
1406
1407 update_option('taxopress_3_23_0_upgrade_completed', true);
1408 } elseif (!get_option('taxopress_3_28_0_upgrade_completed')) {
1409
1410 if (function_exists('taxopress_get_autoterm_data')) {
1411 $autoterms = taxopress_get_autoterm_data();
1412 foreach ($autoterms as $autoterm_index => $autoterm) {
1413 //enable when to fields
1414 $autoterms[$autoterm_index]['autoterm_for_post'] = 1;
1415 $autoterms[$autoterm_index]['autoterm_for_schedule'] = 1;
1416 $autoterms[$autoterm_index]['autoterm_for_existing_content'] = 1;
1417 $autoterms[$autoterm_index]['autoterm_for_metaboxes'] = 1;
1418 // update new cloned fields for other groups
1419 $autoterms[$autoterm_index]['schedule_terms_limit'] = !empty($autoterm['terms_limit']) ? $autoterm['terms_limit'] : 5;
1420 $autoterms[$autoterm_index]['schedule_autoterm_target'] = !empty($autoterm['autoterm_target']) ? $autoterm['autoterm_target'] : 0;
1421 $autoterms[$autoterm_index]['schedule_autoterm_word'] = !empty($autoterm['autoterm_word']) ? $autoterm['autoterm_word'] : 0;
1422 $autoterms[$autoterm_index]['schedule_autoterm_hash'] = !empty($autoterm['autoterm_hash']) ? $autoterm['autoterm_hash'] : 0;
1423
1424 $autoterms[$autoterm_index]['existing_content_terms_limit'] = !empty($autoterm['terms_limit']) ? $autoterm['terms_limit'] : 5;
1425 }
1426 update_option('taxopress_autoterms', $autoterms);
1427 }
1428 update_option('taxopress_3_28_0_upgrade_completed', true);
1429 }
1430 }
1431
1432 /**
1433 * Redirect user on plugin activation
1434 *
1435 * @return void
1436 */
1437 public static function redirect_on_activate()
1438 {
1439 if (get_option('taxopress_activate')) {
1440 delete_option('taxopress_activate');
1441 wp_redirect(admin_url("admin.php?page=st_dashboard&welcome"));
1442 exit;
1443 }
1444 }
1445 }
1446