.notice:not(.taxopress-notice) {
display: none !important;
}
';
}
}
/**
* Plugin action links
*/
public static function plugin_settings_link($links)
{
foreach (self::$enabled_menus as $menu_slug => $menu_title) {
$links[] = '' . $menu_title . '';
}
return $links;
}
/**
* Ajax for saving a feature from dashboard page
*
* Copied from PublishPress Blocks
*
* @return boolean,void Return false if failure, echo json on success
*/
public static function saveDashboardFeature()
{
if (!current_user_can('admin_simple_tags')) {
wp_send_json(__('No permission!', 'simple-tags'), 403);
return false;
}
if (
!wp_verify_nonce(
sanitize_key(wp_unslash($_POST['nonce'])),
'st-admin-js'
)
) {
wp_send_json(__('Invalid nonce token!', 'simple-tags'), 400);
return false;
}
if (empty($_POST['feature'])) {
wp_send_json(__('Error: wrong data', 'simple-tags'), 400);
return false;
}
$feature = sanitize_text_field(wp_unslash($_POST['feature']));
$new_state = sanitize_text_field(wp_unslash($_POST['new_state']));
SimpleTags_Plugin::set_option_value($feature, $new_state);
wp_send_json(true, 200);
}
/**
* Ajax Dispatcher
*/
public static function ajax_check()
{
if (isset($_GET['stags_action']) && 'maybe_create_tag' === $_GET['stags_action'] && isset($_GET['tag'])) {
if (!check_ajax_referer('st-admin-js', 'nonce', false)) {
wp_send_json_error(['message' => __('Security check failed.', 'simple-tags')], 403);
}
$taxonomy = get_taxonomy('post_tag');
if (!$taxonomy || empty($taxonomy->cap->manage_terms) || !current_user_can($taxonomy->cap->manage_terms)) {
wp_send_json_error(['message' => __('Permission denied.', 'simple-tags')], 403);
}
self::maybe_create_tag(sanitize_text_field(wp_unslash($_GET['tag'])));
}
}
/**
* Maybe create a tag, and return the term_id
*
* @param string $tag_name
*/
public static function maybe_create_tag($tag_name = '')
{
$term_id = 0;
//restore & in tag post
$tag_name = sanitize_text_field(str_replace("simpletagand", "&", $tag_name));
$result_term = term_exists($tag_name, 'post_tag', 0);
if (empty($result_term)) {
$result_term = wp_insert_term(
$tag_name,
'post_tag'
);
if (!is_wp_error($result_term)) {
$term_id = (int) $result_term['term_id'];
}
} else {
$term_id = (int) $result_term['term_id'];
}
wp_send_json_success(['term_id' => $term_id]);
}
/**
* Ajax for search posts
*
* @return void
*/
public static function taxopress_search_posts_ajax()
{
if (!check_ajax_referer('st-admin-js', 'nonce', false)) {
wp_send_json_error(['message' => __('Security check failed.', 'simple-tags')]);
}
if (!current_user_can('simple_tags')) {
wp_send_json_error(['message' => __('Permission denied.', 'simple-tags')]);
}
$search = isset($_GET['search']) ? sanitize_text_field(wp_unslash($_GET['search'])) : '';
$paged = max(1, intval($_GET['page'] ?? 1));
$post_type = 'post';
$query = new WP_Query([
'post_type' => $post_type,
'post_status' => 'publish',
'posts_per_page' => 10,
'paged' => $paged,
'orderby' => 'date',
'order' => 'DESC',
'fields' => 'ids'
]);
$results = [];
foreach ($query->posts as $post_id) {
$results[] = [
'id' => $post_id,
'text' => get_the_title($post_id)
];
}
wp_send_json([
'results' => $results,
'more' => $paged < $query->max_num_pages
]);
}
/**
* Test if current URL is not a DEV environnement
*
* Copy from monsterinsights_is_dev_url(), thanks !
*
* @param string $url
*
* @return bool
*/
private static function is_dev_url($url = '')
{
$is_local_url = false;
// Trim it up
$url = strtolower(trim($url));
// Need to get the host...so let's add the scheme so we can use parse_url
if (false === strpos($url, 'http://') && false === strpos($url, 'https://')) {
$url = 'http://' . $url;
}
$url_parts = wp_parse_url($url);
$host = !empty($url_parts['host']) ? $url_parts['host'] : false;
if (!empty($url) && !empty($host)) {
if (false !== ip2long($host)) {
if (!filter_var($host, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
$is_local_url = true;
}
} elseif ('localhost' === $host) {
$is_local_url = true;
}
$tlds_to_check = array('.local', ':8888', ':8080', ':8081', '.invalid', '.example', '.test');
foreach ($tlds_to_check as $tld) {
if (false !== strpos($host, $tld)) {
$is_local_url = true;
break;
}
}
if (substr_count($host, '.') > 1) {
$subdomains_to_check = array('dev.', '*.staging.', 'beta.', 'test.');
foreach ($subdomains_to_check as $subdomain) {
$subdomain = str_replace('.', '(.)', $subdomain);
$subdomain = str_replace(array('*', '(.)'), '(.*)', $subdomain);
if (preg_match('/^(' . $subdomain . ')/', $host)) {
$is_local_url = true;
break;
}
}
}
}
return $is_local_url;
}
/**
* Init taxonomy class variable, load this action after all actions on init !
* Make a public static function for call it from children class...
*
* @return void
* @author WebFactory Ltd
*/
public static function register_taxonomy()
{
add_action('init', array(__CLASS__, 'init'), 99999999);
}
/**
* Put in var class the current taxonomy choose by the user
*
* @return void
* @author WebFactory Ltd
*/
public static function init()
{
self::$taxo_name = esc_html__('Post tags', 'simple-tags');
self::$post_type_name = esc_html__('Posts', 'simple-tags');
// Custom CPT ?
if (isset($_GET['cpt']) && !empty($_GET['cpt']) && post_type_exists(sanitize_text_field(wp_unslash($_GET['cpt'])))) {
$cpt = get_post_type_object(sanitize_text_field(wp_unslash($_GET['cpt'])));
self::$post_type = $cpt->name;
self::$post_type_name = $cpt->labels->name;
}
// Get compatible taxo for current post type
$compatible_taxonomies = get_object_taxonomies(self::$post_type);
// Custom taxo ?
if (isset($_GET['taxo']) && !empty($_GET['taxo']) && taxonomy_exists(sanitize_text_field(wp_unslash($_GET['taxo'])))) {
$taxo = get_taxonomy(sanitize_text_field(wp_unslash($_GET['taxo'])));
// Taxo is compatible ?
if (in_array($taxo->name, $compatible_taxonomies)) {
self::$taxonomy = $taxo->name;
self::$taxo_name = $taxo->labels->name;
} else {
unset($taxo);
}
}
// Default taxo from CPT...
if (!isset($taxo) && is_array($compatible_taxonomies) && !empty($compatible_taxonomies)) {
// Take post_tag before category
if (in_array('post_tag', $compatible_taxonomies, true)) {
$taxo = get_taxonomy('post_tag');
} else {
$taxo = get_taxonomy(current($compatible_taxonomies));
}
self::$taxonomy = $taxo->name;
self::$taxo_name = $taxo->labels->name;
// TODO: Redirect for help user that see the URL...
} elseif (!isset($taxo)) {
// TODO: We can't wp_die on init as it affect all pages
//wp_die(esc_html__('This custom post type not have taxonomies.', 'simple-tags'));
}
// Free memory
unset($cpt, $taxo);
}
/**
* Build HTML form for allow user to change taxonomy for the current page.
*
* @param string $page_value
*
* @return void
* @author Olatechpro
*/
public static function boxSelectorTaxonomy($page_value = '')
{
echo '
' . PHP_EOL;
echo '
' . PHP_EOL;
echo '' . PHP_EOL;
echo '
' . PHP_EOL;
echo '
' . PHP_EOL;
}
public static function tabSelectorTaxonomy($tab_slug = '', $page_slug = '')
{
$current_taxo = isset($_GET["{$tab_slug}_taxo"]) ? sanitize_text_field(wp_unslash($_GET["{$tab_slug}_taxo"])) : get_option("{$tab_slug}_taxo", '');
$current_cpt = isset($_GET["{$tab_slug}_cpt"]) ? sanitize_text_field(wp_unslash($_GET["{$tab_slug}_cpt"])) : get_option("{$tab_slug}_cpt", '');
// Fallbacks if not yet set
if (empty($current_cpt)) {
foreach (get_post_types(['show_ui' => true], 'objects') as $pt) {
if (!empty(get_object_taxonomies($pt->name))) {
$current_cpt = $pt->name;
break;
}
}
}
if (empty($current_taxo) && $current_cpt) {
$possible_taxos = get_object_taxonomies($current_cpt);
if (!empty($possible_taxos)) {
$current_taxo = $possible_taxos[0];
}
}
// Save for use elsewhere
self::$post_type = $current_cpt;
self::$taxonomy = $current_taxo;
// Update $post_type_name dynamically
if ($current_cpt) {
$post_type_object = get_post_type_object($current_cpt);
if ($post_type_object) {
self::$post_type_name = $post_type_object->labels->name;
}
}
// Save to DB for persistence
update_option("{$tab_slug}_taxo", $current_taxo);
update_option("{$tab_slug}_cpt", $current_cpt);
// Build list of post types and taxonomies (only CPTs with taxonomies)
$taxonomies = [];
echo '' . PHP_EOL;
echo '
' . PHP_EOL;
echo '' . PHP_EOL;
echo '
' . PHP_EOL;
echo '
' . PHP_EOL;
}
public function maybe_enqueue_frontend_assets_in_admin()
{
$screen = get_current_screen();
if (!$screen) {
return;
}
if (strpos($screen->id, 'taxopress_page_') === false) {
return;
}
$is_edit_mode = isset($_GET['action']) && in_array($_GET['action'], ['edit'], true);
if (!$is_edit_mode) {
return;
}
$current_page = isset($_GET['page']) ? sanitize_text_field(wp_unslash($_GET['page'])) : '';
// List of pages that need preview functionality
$preview_pages = [
'st_terms_display',
'st_related_posts',
'st_post_tags',
];
if (!in_array($current_page, $preview_pages, true)) {
return;
}
if ((int) SimpleTags_Plugin::get_option_value('disable_admin_frontend_scripts') === 1) {
return;
}
if (! apply_filters('taxopress_load_admin_frontend_scripts', true)) {
return;
}
// Register and enqueue assets
wp_register_script('taxopress-frontend-js', STAGS_URL . '/assets/frontend/js/frontend.js', array('jquery'), STAGS_VERSION);
wp_register_style('taxopress-frontend-css', STAGS_URL . '/assets/frontend/css/frontend.css', array(), STAGS_VERSION, 'all');
// Enqueue the assets
wp_enqueue_script('taxopress-frontend-js');
wp_enqueue_style('taxopress-frontend-css');
}
/**
* Init somes JS and CSS need for TaxoPress.
*
* @return void
* @author WebFactory Ltd
*/
public static function admin_enqueue_scripts()
{
global $pagenow;
$select_2_page = false;
if ((isset($_GET['page']) && in_array($_GET['page'], ['st_posts', 'st_terms', 'st_autolinks', 'st_autoterms', 'st_autoterms_schedule', 'st_terms_display', 'st_related_posts', 'st_post_tags', 'st_mass_terms'])) || in_array($pagenow, ['post.php', 'edit.php', 'post-new.php'])) {
$select_2_page = true;
}
do_action('taxopress_admin_class_before_assets_register');
//color picker style
wp_enqueue_style('wp-color-picker');
// Helper TaxoPress
wp_register_script('st-helper-add-tags', STAGS_URL . '/assets/js/helper-add-tags.js', array('jquery'), STAGS_VERSION);
wp_localize_script('st-helper-add-tags', 'stHelperAddTagsL10n', [
'nonce' => wp_create_nonce('st-admin-js'),
]);
wp_register_script('st-helper-options', STAGS_URL . '/assets/js/helper-options.js', array('jquery', 'wp-color-picker'), STAGS_VERSION);
// Register CSS
wp_register_style('st-admin', STAGS_URL . '/assets/css/admin.css', array(), STAGS_VERSION, 'all');
wp_register_style('st-admin-global', STAGS_URL . '/assets/css/admin-global.css', array(), STAGS_VERSION, 'all');
// Register tooltip
wp_register_script(
'taxopress-admin-tooltip',
STAGS_URL . '/assets/lib/tooltip/js/tooltip.min.js',
['jquery'],
STAGS_VERSION
);
wp_register_style(
'taxopress-admin-tooltip',
STAGS_URL . '/assets/lib/tooltip/css/tooltip.min.css',
[],
STAGS_VERSION
);
//enqueue tooltip
wp_enqueue_script('taxopress-admin-tooltip');
wp_enqueue_style('taxopress-admin-tooltip');
// Register Select 2
wp_register_script(
'taxopress-admin-select2',
STAGS_URL . '/assets/lib/select2/js/select2.full.min.js',
['jquery'],
STAGS_VERSION
);
wp_register_style(
'taxopress-admin-select2',
STAGS_URL . '/assets/lib/select2/css/select2.min.css',
[],
STAGS_VERSION
);
if ($select_2_page) {
wp_enqueue_script('taxopress-admin-select2');
wp_enqueue_style('taxopress-admin-select2');
}
//Register and enqueue admin js
$script_dependencies = ['jquery'];
if ($select_2_page) {
$script_dependencies[] = 'taxopress-admin-select2';
$script_dependencies[] = 'wp-util';
}
$taxopress_pages = taxopress_admin_pages();
if (isset($_GET['page']) && in_array($_GET['page'], $taxopress_pages)) {
wp_enqueue_media();
}
wp_register_script('st-admin-js', STAGS_URL . '/assets/js/admin.js', $script_dependencies, STAGS_VERSION);
wp_enqueue_script('st-admin-js');
//localize script
wp_localize_script('st-admin-js', 'st_admin_localize', [
'ajaxurl' => admin_url('admin-ajax.php'),
'select_valid' => esc_html__('Please select a valid', 'simple-tags'),
'check_nonce' => wp_create_nonce('st-admin-js'),
'select_default_label' => esc_html__('Select Default Post Thumb', 'simple-tags'),
'use_media_label' => esc_html__('Use this media', 'simple-tags'),
'existing_content_admin_label' => esc_html__('Edit the current setting.', 'simple-tags'),
'request_error' => esc_html__('The request could not be completed. Please try again.', 'simple-tags'),
'autoterm_admin_url' => admin_url('admin.php?page=st_autoterms'),
'no_terms_message' => esc_html__('No terms will be deleted', 'simple-tags'),
'terms_count_message' => esc_html__(' terms will be deleted.', 'simple-tags'),
'checking_terms_message' => esc_html__('Checking terms...', 'simple-tags'),
'terms_error' => esc_html__('An error occurred while checking terms.', 'simple-tags'),
'post_required' => esc_html__('Select a post to see a preview.', 'simple-tags'),
'save_settings' => esc_html__('Auto Term ID missing. Kindly save the auto term before using this feature.', 'simple-tags'),
'delete_label' => esc_html__('Delete', 'simple-tags'),
'ai_nonce' => wp_create_nonce('taxopress-ai-ajax-nonce'),
'post_title' => '%post_title%',
'post_permalink' => '%post_permalink%',
'post_date' => '%post_date%',
'post_thumb_url' => '%post_thumb_url%',
'post_category' => '%post_category%',
'post_size' => '%post_size%',
'post_color' => '%post_color%',
'merge_cancelled' => esc_html__('Merge has been cancelled.', 'simple-tags'),
'cancel_label' => esc_html__('Cancel', 'simple-tags'),
'paused_label' => esc_html__('Pause.', 'simple-tags'),
'continue_label' => esc_html__('Continue', 'simple-tags'),
'merge_in_progress' => esc_html__('Merging terms. Please wait...', 'simple-tags'),
'merge_attached_data' => esc_html__('Merging %1$s terms attached to %2$s posts. Please wait...', 'simple-tags'),
'merge_large_data' => esc_html__('Large dataset detected, terms will be merged in batches of 20!', 'simple-tags'),
'merge_none_merged' => esc_html__('No terms were merged.', 'simple-tags'),
'batch_merge_progress' => esc_html__('Batch %1$s of %2$s merged.', 'simple-tags'),
'terms_merged_text' => esc_html__('terms merged', 'simple-tags'),
'posts_updated_text' => esc_html__('posts updated', 'simple-tags'),
'merge_success_update' => esc_html__('All terms merged into %s', 'simple-tags'),
'ajax_merge_terms_error' => esc_html__('AJAX error on batch', 'simple-tags'),
'batch_error_text' => esc_html__('Error on batch %1$s:', 'simple-tags'),
'enable_merge_terms_slug' => SimpleTags_Plugin::get_option_value('enable_merge_terms_slug'),
'enable_add_terms_slug' => SimpleTags_Plugin::get_option_value('enable_add_terms_slug'),
'enable_remove_terms_slug' => SimpleTags_Plugin::get_option_value('enable_remove_terms_slug'),
'enable_rename_terms_slug' => SimpleTags_Plugin::get_option_value('enable_rename_terms_slug'),
'enable_mass_edit_terms_slug' => SimpleTags_Plugin::get_option_value('enable_mass-edit_terms_slug'),
'select_post_label' => esc_html__('Search Posts...', 'simple-tags'),
'loading' => esc_html__('Loading...', 'simple-tags'),
'preview_error' => esc_html__('Error loading preview', 'simple-tags'),
'enable_ibm_watson_ai_source' => SimpleTags_Plugin::get_option_value('enable_ibm_watson_ai_source'),
'enable_dandelion_ai_source' => SimpleTags_Plugin::get_option_value('enable_dandelion_ai_source'),
'enable_lseg_ai_source' => SimpleTags_Plugin::get_option_value('enable_lseg_ai_source'),
'plugin_url' => STAGS_URL,
'using_default_text' => __('Using default TaxoPress image', 'simple-tags'),
'select_image_label' => esc_html__('Select Media', 'simple-tags'),
'change_image_label' => esc_html__('Change Media', 'simple-tags'),
'use_default_label' => esc_html__('Use Default', 'simple-tags'),
'see_more_suggestions' => esc_html__('See More', 'simple-tags'),
'see_less_suggestions' => esc_html__('See Less', 'simple-tags'),
'apply_selected' => esc_html__('Apply Selected', 'simple-tags'),
'close_suggestions' => esc_html__('Close', 'simple-tags'),
'select_suggestion_alert' => esc_html__('Please select at least one suggestion to apply.', 'simple-tags'),
'multiple_merge_warning' => esc_html__('You have selected multiple merge suggestions. All selected terms will be merged into a single new term. Do you want to continue?', 'simple-tags'),
'no_merge_suggestions' => esc_html__('No merge suggestions found for this taxonomy.', 'simple-tags'),
'suggested_terms_title' => esc_html__('Suggested Terms to Merge:', 'simple-tags'),
'duplicates_text' => esc_html__('duplicates', 'simple-tags'),
'reason_text' => esc_html__('Reason:', 'simple-tags'),
'select_all_label' => esc_html__('Select All', 'simple-tags'),
'deselect_all_label' => esc_html__('Deselect All', 'simple-tags'),
'terms_to_merge_text' => esc_html__('Terms to Merge', 'simple-tags'),
'new_term_text' => esc_html__('New Term', 'simple-tags'),
'reasons_text' => esc_html__('Reasons', 'simple-tags'),
]);
//Register remodal assets
wp_register_script('st-remodal-js', STAGS_URL . '/assets/js/remodal.min.js', array('jquery'), STAGS_VERSION);
wp_register_style('st-remodal-css', STAGS_URL . '/assets/css/remodal.css', array(), STAGS_VERSION, 'all');
wp_register_style('st-remodal-default-theme-css', STAGS_URL . '/assets/css/remodal-default-theme.css', array(), STAGS_VERSION, 'all');
// Register location
$wp_post_pages = array('post.php', 'post-new.php');
$wp_page_pages = array('page.php', 'page-new.php');
wp_enqueue_style('st-admin-global');
// Common Helper for Post, Page and Plugin Page
if (
in_array($pagenow, $wp_post_pages) ||
(in_array($pagenow, $wp_page_pages) && is_page_have_tags()) ||
(isset($_GET['page']) && in_array($_GET['page'], $taxopress_pages))
) {
wp_enqueue_script('st-remodal-js');
wp_enqueue_style('st-remodal-css');
wp_enqueue_style('st-remodal-default-theme-css');
wp_enqueue_style('st-admin');
do_action('taxopress_admin_class_after_styles_enqueue');
}
// add jQuery tabs for options page. Use jQuery UI Tabs from WP
if (isset($_GET['page']) && in_array($_GET['page'], array('st_options', 'st_terms_display', 'st_post_tags', 'st_related_posts',))) {
wp_enqueue_script('jquery-ui-tabs');
wp_enqueue_script('st-helper-options');
}
do_action('taxopress_admin_class_after_assets_enqueue');
}
/**
* Add settings page on WordPress admin menu
*
* @return void
* @author WebFactory Ltd
*/
public static function admin_menu()
{
self::$admin_url = admin_url('admin.php?page=' . self::MENU_SLUG);
add_menu_page(
__('TaxoPress: Options', 'simple-tags'),
__('TaxoPress', 'simple-tags'),
'admin_simple_tags',
self::MENU_SLUG,
array(
__CLASS__,
'page_options',
),
'dashicons-tag',
69
);
add_submenu_page(
self::MENU_SLUG,
__('TaxoPress: Options', 'simple-tags'),
__('Settings', 'simple-tags'),
'admin_simple_tags',
self::MENU_SLUG,
array(
__CLASS__,
'page_options',
)
);
}
/**
* Build HTML for page options, manage also save/reset settings
*
* @return void
* @author WebFactory Ltd
*/
public static function page_options()
{
// Get options
$options = (array) SimpleTags_Plugin::get_option();
if (current_user_can('admin_simple_tags')) {
// Update or reset options
if (isset($_POST['updateoptions'])) {
$dashboard_options = taxopress_dashboard_options();
$dashboard_option_keys = array_column($dashboard_options, 'option_key');
check_admin_referer('updateresetoptions-simpletags');
$sanitized_options = [];
$is_fast_update_submission = isset($_GET['page']) && $_GET['page'] === 'st_taxopress_ai';
// This settings has been migrated to fast update screen so only update from there
if ($is_fast_update_submission) {
// add taxopress ai post type and taxonomies options so we can have all post types. TODO: This need to be a filter
foreach (get_post_types(['public' => true], 'names') as $post_type => $post_type_object) {
if ($post_type == 'post') {
$opt_default_value = 'post_tag';
} else {
$opt_default_value = 0;
}
$options['taxopress_ai_' . $post_type . '_metabox_default_taxonomy'] = $opt_default_value;
$options['taxopress_ai_' . $post_type . '_metabox_display_option'] = 'default';
$options['taxopress_ai_' . $post_type . '_support_private_taxonomy'] = 0;
$options['taxopress_ai_' . $post_type . '_metabox_orderby'] = 'count';
$options['taxopress_ai_' . $post_type . '_metabox_order'] = 'desc';
$options['taxopress_ai_' . $post_type . '_metabox_maximum_terms'] = 45;
$options['taxopress_ai_' . $post_type . '_metabox_show_post_count'] = 0;
$options['taxopress_ai_' . $post_type . '_metabox_show_term_slug'] = 0;
$options['taxopress_ai_' . $post_type . '_minimum_term_length'] = 2;
$options['taxopress_ai_' . $post_type . '_maximum_term_length'] = 40;
$options['taxopress_ai_' . $post_type . '_exclusions'] = '';
$options['enable_taxopress_ai_' . $post_type . '_metabox'] = $opt_default_value;
$options['taxopress_ai_' . $post_type . '_metabox_filters'] = 1;
foreach (['post_terms', 'existing_terms', 'suggest_local_terms', 'create_terms'] as $taxopress_ai_tab) {
$options['enable_taxopress_ai_' . $post_type . '_' . $taxopress_ai_tab . '_tab'] = $opt_default_value;
}
}
// add metabox post type and taxonomies options so we can have all post types. TODO: This need to be a filter
foreach (taxopress_get_all_wp_roles() as $role_name => $role_info) {
if (in_array($role_name, ['administrator', 'editor', 'author', 'contributor'])) {
$enable_acess_default_value = 1;
} else {
$enable_acess_default_value = 0;
}
$options['enable_' . $role_name . '_metabox'] = $enable_acess_default_value;
$options['enable_restrict' . $role_name . '_metabox'] = $enable_acess_default_value;
// ONLY admin + editor default to can edit
if (!isset($options['enable_edit_' . $role_name . '_metabox'])) {
$options['enable_edit_' . $role_name . '_metabox'] = in_array($role_name, ['administrator', 'editor']) ? 1 : 0;
}
$options['enable_metabox_' . $role_name . ''] = [];
$options['remove_taxonomy_metabox_' . $role_name . ''] = [];
}
}
foreach ($options as $key => $value) {
// If this is NOT a Fast Update submission, preserve metabox/metabox-access keys
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)) {
// Keep existing value as-is
if (!is_array($value)) {
$sanitized_options[$key] = taxopress_sanitize_text_field($value);
} else {
$sanitized_options[$key] = map_deep($value, 'sanitize_text_field');
}
continue;
}
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
$post_value = isset($_POST[$key]) ? wp_unslash($_POST[$key]) : '';
if (empty($post_value) && in_array($key, $dashboard_option_keys)) {
$post_value = SimpleTags_Plugin::get_option_value($key);
}
if (!is_array($post_value)) {
$sanitized_options[$key] = taxopress_sanitize_text_field($post_value);
} else {
$sanitized_options[$key] = map_deep($post_value, 'sanitize_text_field');
}
}
$options = $sanitized_options;
SimpleTags_Plugin::set_option($options);
do_action('simpletags_settings_save_general_end');
do_action('taxopress_settings_saved');
add_settings_error(__CLASS__, __CLASS__, esc_html__('Options saved', 'simple-tags'), 'updated taxopress-notice');
} elseif (isset($_POST['reset_options'])) {
check_admin_referer('updateresetoptions-simpletags');
SimpleTags_Plugin::set_default_option();
add_settings_error(__CLASS__, __CLASS__, esc_html__('TaxoPress options resetted to default options!', 'simple-tags'), 'updated taxopress-notice');
} else {
//add_settings_error(__CLASS__, __CLASS__, esc_html__('Settings updated', 'simple-tags'), 'updated');
}
}
settings_errors(__CLASS__);
include STAGS_DIR . '/views/admin/page-settings.php';
}
/**
* Get terms for a post, format terms for input and autocomplete usage
*
* @param string $taxonomy
* @param integer $post_id
*
* @return string
* @author WebFactory Ltd
*/
public static function getTermsToEdit($taxonomy = 'post_tag', $post_id = 0)
{
$post_id = (int) $post_id;
if (!$post_id) {
return '';
}
$is_mass_edit_page = isset($_GET['page']) && $_GET['page'] === 'st_mass_terms';
$show_slug = SimpleTags_Plugin::get_option_value('enable_mass-edit_terms_slug');
if ($is_mass_edit_page) {
$term_objects = wp_get_post_terms($post_id, $taxonomy);
if (empty($term_objects) || is_wp_error($term_objects)) {
return '';
}
$terms = array();
foreach ($term_objects as $term) {
if ($show_slug) {
if (!empty($term->slug)) {
$terms[] = $term->name . ' (' . $term->slug . ')';
} else {
$terms[] = $term->name;
}
} else {
$terms[] = $term->name;
}
}
$terms = join(', ', $terms);
} else {
$terms = wp_get_post_terms($post_id, $taxonomy, array('fields' => 'names'));
if (empty($terms) || is_wp_error($terms)) {
return '';
}
$terms = array_unique($terms);
$terms = join(', ', $terms);
}
$terms = esc_attr($terms);
$terms = apply_filters('tags_to_edit', $terms);
return $terms;
}
/**
* Default content for meta box of TaxoPress
*
* @return string
* @author WebFactory Ltd
*/
public static function getDefaultContentBox()
{
if ((int) wp_count_terms(array('taxonomy' => 'post_tag', 'hide_empty' => false)) == 0) { // TODO: Custom taxonomy
return esc_html__('This feature requires at least 1 tag to work. Begin by adding tags!', 'simple-tags');
} else {
return esc_html__('This feature works only with activated JavaScript. Activate it in your Web browser so you can!', 'simple-tags');
}
}
/**
* A short public static function for display the same copyright on all admin pages
*
* @return void
* @author WebFactory Ltd
*/
public static function printAdminFooter()
{
/* ?>
$options) {
$colspan = count($options) > 1 ? 'colspan="2"' : '';
if ($section === 'legacy') {
$table_sub_tab = '
' . esc_html__("Tag Cloud", "simple-tags") . ' |
' . esc_html__("Tags for Current Post", "simple-tags") . ' |
' . esc_html__("Related Posts", "simple-tags") . ' |
' . esc_html__("Auto Links", "simple-tags") . '
' . PHP_EOL;
} elseif ($section === 'taxopress-ai') {
$table_sub_tab_lists = [];
$pt_index = 0;
foreach (TaxoPressAiUtilities::get_post_types_options() as $post_type => $post_type_object) {
if (!in_array($post_type, ['attachment'])) {
$active_pt = ($pt_index === 0) ? 'active' : '';
$table_sub_tab_lists[] = '' . esc_html($post_type_object->labels->name) . '';
$pt_index++;
}
}
$table_sub_tab = '' . join(' | ', $table_sub_tab_lists) . '
' . PHP_EOL;
} elseif ($section === 'metabox') {
$table_sub_tab_lists = [];
$pt_index = 0;
foreach (taxopress_get_all_wp_roles() as $role_name => $role_info) {
$active_pt = ($pt_index === 0) ? 'active' : '';
$table_sub_tab_lists[] = '' . esc_html(translate_user_role($role_info['name'])) . '';
$pt_index++;
}
$table_sub_tab = '' . join(' | ', $table_sub_tab_lists) . '
' . PHP_EOL;
} else {
$table_sub_tab = '';
}
$output .= '' . PHP_EOL;
$output .= $table_sub_tab;
$output .= '
' . PHP_EOL;
$output .= '
' . PHP_EOL;
}
return $output;
}
/**
* Get nice title for tabs title option
*
* @param string $id
*
* @return string
*/
public static function getNiceTitleOptions($id = '')
{
switch ($id) {
case 'administration':
return esc_html__('Administration', 'simple-tags');
case 'auto-links':
return esc_html__('Auto link', 'simple-tags');
case 'features':
return esc_html__('Features', 'simple-tags');
case 'embeddedtags':
return esc_html__('Embedded Tags', 'simple-tags');
case 'tagspost':
return esc_html__('Tags for Current Post', 'simple-tags');
case 'relatedposts':
return esc_html__('Related Posts', 'simple-tags');
case 'legacy':
return esc_html__('Legacy', 'simple-tags');
case 'posts':
return esc_html__('Posts', 'simple-tags');
case 'taxopress-ai':
return esc_html__('Metaboxes', 'simple-tags');
case 'metabox':
return esc_html__('Metabox Access', 'simple-tags');
case 'linked_terms':
return esc_html__('Linked Terms', 'simple-tags');
case 'synonyms':
return esc_html__('Term Synonyms', 'simple-tags');
case 'licence':
return esc_html__('License', 'simple-tags');
case 'hidden_terms':
return esc_html__('Hidden Terms', 'simple-tags');
case 'frontend_scripts':
return esc_html__('Frontend Scripts', 'simple-tags');
case 'manage_terms':
return esc_html__('Manage Terms', 'simple-tags');
case 'mass_edit_terms':
return esc_html__('Mass Edit Terms', 'simple-tags');
case 'core_linked_terms':
return esc_html__('Linked Terms', 'simple-tags');
case 'core_synonyms_terms':
return esc_html__('Term Synonyms', 'simple-tags');
case 'legacy_ai_sources':
return esc_html__('Auto Terms', 'simple-tags');
}
return '';
}
/**
* This method allow to check if the DB is up to date, and if a upgrade is need for options
* TODO, useful or delete ?
*
* @return void
* @author WebFactory Ltd
*/
public static function upgrade()
{
// Get current version number
$current_version = get_option(STAGS_OPTIONS_NAME . '-version');
// Upgrade needed ?
if ($current_version == false || version_compare($current_version, STAGS_VERSION, '<')) {
$current_options = get_option(STAGS_OPTIONS_NAME);
$default_options = (array) include(STAGS_DIR . '/inc/helper.options.default.php');
// Add new options
foreach ($default_options as $key => $default_value) {
if (!isset($current_options[$key])) {
$current_options[$key] = $default_value;
}
}
// Remove old options
/*foreach ($current_options as $key => $current_value) {
if (!isset($default_options[$key])) {
unset($current_options[$key]);
}
}*/
update_option(STAGS_OPTIONS_NAME . '-version', STAGS_VERSION);
update_option(STAGS_OPTIONS_NAME, $current_options);
}
}
/**
* Make a simple SQL query with some args for get terms for ajax display
*
* @param string $taxonomy
* @param string $search
* @param string $order_by
* @param string $order
*
* @return array
* @author WebFactory Ltd
*/
public static function getTermsForAjax($taxonomy = 'post_tag', $search = '', $order_by = 'name', $order = 'ASC', $limit = 0)
{
global $wpdb;
$order = strtoupper($order);
if (!in_array($order, ['ASC', 'DESC'], true)) {
$order = 'ASC';
}
$allowed_orderby = [
'name' => 't.name',
'count' => 'tt.count',
'random' => 'RAND()',
];
if (isset($allowed_orderby[$order_by])) {
$order_by_sql = $allowed_orderby[$order_by];
} else {
$order_by_sql = $allowed_orderby['name'];
}
$limit_sql = '';
$limit = (int) $limit;
if ($limit > 0) {
$limit_sql = $wpdb->prepare('LIMIT 0, %d', $limit);
}
if ($taxonomy == 'linked_term_taxonomies') {
$taxonomies = SimpleTags_Plugin::get_option_value('linked_terms_taxonomies');
if (empty($taxonomies) || !is_array($taxonomies)) {
$taxonomies = ['category', 'post_tag'];
}
$taxonomies_list = "'" . implode("', '", $taxonomies) . "'";
}
if (!empty($search)) {
if ($taxonomy == 'linked_term_taxonomies') {
$query = $wpdb->prepare(
"
SELECT DISTINCT t.name, t.term_id, tt.taxonomy
FROM {$wpdb->terms} AS t
INNER JOIN {$wpdb->term_taxonomy} AS tt ON t.term_id = tt.term_id
WHERE tt.taxonomy IN ($taxonomies_list)
AND t.name LIKE %s
ORDER BY $order_by_sql $order $limit_sql
",
'%' . $wpdb->esc_like($search) . '%'
);
} else {
$query = $wpdb->prepare(
"
SELECT DISTINCT t.name, t.slug, t.term_id, tt.taxonomy
FROM {$wpdb->terms} AS t
INNER JOIN {$wpdb->term_taxonomy} AS tt ON t.term_id = tt.term_id
WHERE tt.taxonomy = %s
AND t.name LIKE %s
ORDER BY $order_by_sql $order $limit_sql
",
$taxonomy,
'%' . $wpdb->esc_like($search) . '%'
);
}
return $wpdb->get_results($query);
} else {
if ($taxonomy == 'linked_term_taxonomies') {
$query = "
SELECT DISTINCT t.name, t.term_id, tt.taxonomy
FROM {$wpdb->terms} AS t
INNER JOIN {$wpdb->term_taxonomy} AS tt ON t.term_id = tt.term_id
WHERE tt.taxonomy IN ($taxonomies_list)
ORDER BY $order_by_sql $order $limit_sql
";
} else {
$query = $wpdb->prepare("
SELECT DISTINCT t.name, t.slug, t.term_id, tt.taxonomy
FROM {$wpdb->terms} AS t
INNER JOIN {$wpdb->term_taxonomy} AS tt ON t.term_id = tt.term_id
WHERE tt.taxonomy = %s
ORDER BY $order_by_sql $order $limit_sql
", $taxonomy);
}
return $wpdb->get_results($query);
}
}
/**
* Plugin installer/uograde code
*
* @return void
*/
public static function plugin_installer_upgrade_code()
{
if (!get_option('taxopress_3_23_0_upgrade_completed')) {
$options = SimpleTags_Plugin::get_option();
// add metabox default values
$tax_names = array_keys(get_taxonomies([], 'names'));
foreach (taxopress_get_all_wp_roles() as $role_name => $role_info) {
if (in_array($role_name, ['administrator', 'editor', 'author', 'contributor'])) {
$enable_acess_default_value = 1;
} else {
$enable_acess_default_value = 0;
}
$options['enable_' . $role_name . '_metabox'] = $enable_acess_default_value;
$options['enable_metabox_' . $role_name . ''] = $tax_names;
$options['remove_taxonomy_metabox_' . $role_name . ''] = [];
}
SimpleTags_Plugin::set_option($options);
update_option('taxopress_3_23_0_upgrade_completed', true);
} elseif (!get_option('taxopress_3_28_0_upgrade_completed')) {
if (function_exists('taxopress_get_autoterm_data')) {
$autoterms = taxopress_get_autoterm_data();
foreach ($autoterms as $autoterm_index => $autoterm) {
//enable when to fields
$autoterms[$autoterm_index]['autoterm_for_post'] = 1;
$autoterms[$autoterm_index]['autoterm_for_schedule'] = 1;
$autoterms[$autoterm_index]['autoterm_for_existing_content'] = 1;
$autoterms[$autoterm_index]['autoterm_for_metaboxes'] = 1;
// update new cloned fields for other groups
$autoterms[$autoterm_index]['schedule_terms_limit'] = !empty($autoterm['terms_limit']) ? $autoterm['terms_limit'] : 5;
$autoterms[$autoterm_index]['schedule_autoterm_target'] = !empty($autoterm['autoterm_target']) ? $autoterm['autoterm_target'] : 0;
$autoterms[$autoterm_index]['schedule_autoterm_word'] = !empty($autoterm['autoterm_word']) ? $autoterm['autoterm_word'] : 0;
$autoterms[$autoterm_index]['schedule_autoterm_hash'] = !empty($autoterm['autoterm_hash']) ? $autoterm['autoterm_hash'] : 0;
$autoterms[$autoterm_index]['existing_content_terms_limit'] = !empty($autoterm['terms_limit']) ? $autoterm['terms_limit'] : 5;
}
update_option('taxopress_autoterms', $autoterms);
}
update_option('taxopress_3_28_0_upgrade_completed', true);
}
}
/**
* Redirect user on plugin activation
*
* @return void
*/
public static function redirect_on_activate()
{
if (get_option('taxopress_activate')) {
delete_option('taxopress_activate');
wp_redirect(admin_url("admin.php?page=st_dashboard&welcome"));
exit;
}
}
}