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

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