$tax['name'], 'text' => $text, ]; } $current = taxopress_get_current_taxonomy(); $select['selected'] = $current; /** * Filters the taxonomy dropdown options before rendering. * * @param array $select Array of options for the dropdown. * @param array $taxonomies Array of original passed in post types. */ $select = apply_filters('taxopress_taxonomies_dropdown_options', $select, $taxonomies); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped echo $ui->get_select_input([ 'namearray' => 'taxopress_selected_taxonomy', 'name' => 'taxonomy', 'selections' => $select,// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped 'wrap' => false, ]); } } /** * Get the selected taxonomy from the $_POST global. * * * @param bool $taxonomy_deleted Whether or not a taxonomy was recently deleted. Optional. Default false. * @return bool|string False on no result, sanitized taxonomy if set. * @internal * */ function taxopress_get_current_taxonomy($taxonomy_deleted = false) { $tax = false; if (!empty($_POST)) { if (!empty($_POST['taxopress_select_taxonomy_nonce_field'])) { check_admin_referer('taxopress_select_taxonomy_nonce_action', 'taxopress_select_taxonomy_nonce_field'); } if (isset($_POST['taxopress_selected_taxonomy']['taxonomy'])) { $tax = sanitize_text_field($_POST['taxopress_selected_taxonomy']['taxonomy']); } elseif ($taxonomy_deleted) { $taxonomies = taxopress_get_taxonomy_data(); $tax = key($taxonomies); } elseif (isset($_POST['cpt_custom_tax']['name'])) { // Return the submitted value. if (!in_array($_POST['cpt_custom_tax']['name'], taxopress_reserved_taxonomies(), true)) { $tax = sanitize_text_field($_POST['cpt_custom_tax']['name']); } else { // Return the original value since user tried to submit a reserved term. $tax = sanitize_text_field($_POST['tax_original']); } } } elseif (!empty($_GET) && isset($_GET['taxopress_taxonomy'])) { $tax = sanitize_text_field($_GET['taxopress_taxonomy']); } else { $taxonomies = taxopress_get_taxonomy_data(); if (!empty($taxonomies)) { // Will return the first array key. $tax = key($taxonomies); } } /** * Filters the current taxonomy to edit. * * @param string $tax Taxonomy slug. */ return apply_filters('taxopress_current_taxonomy', $tax); } /** * Delete our custom taxonomy from the array of taxonomies. * * * @param array $data The $_POST values. Optional. * @return bool|string False on failure, string on success. * @internal * */ function taxopress_delete_taxonomy($data = []) { if (is_string($data) && taxonomy_exists($data)) { $data = [ 'cpt_custom_tax' => [ 'name' => $data, ], ]; } // Check if they selected one to delete. if (empty($data['cpt_custom_tax']['name'])) { return taxopress_admin_notices('error', '', false, esc_html__('Please provide a taxonomy to delete', 'simple-tags')); } /** * Fires before a taxonomy is deleted from our saved options. * * * @param array $data Array of taxonomy data we are deleting. */ do_action('taxopress_before_delete_taxonomy', $data); $taxonomies = taxopress_get_taxonomy_data(); if (array_key_exists(strtolower($data['cpt_custom_tax']['name']), $taxonomies)) { unset($taxonomies[$data['cpt_custom_tax']['name']]); /** * Filters whether or not 3rd party options were saved successfully within taxonomy deletion. * * @param bool $value Whether or not someone else saved successfully. Default false. * @param array $taxonomies Array of our updated taxonomies data. * @param array $data Array of submitted taxonomy to update. */ if (false === ($success = apply_filters('taxopress_taxonomy_delete_tax', false, $taxonomies, $data))) { $success = update_option('taxopress_taxonomies', $taxonomies); } } if ($data['cpt_custom_tax']['name'] === 'media_tag') { $success = update_option('taxopress_media_tag_deleted', 1); } delete_option("default_term_{$data['cpt_custom_tax']['name']}"); /** * Fires after a taxonomy is deleted from our saved options. * * * @param array $data Array of taxonomy data that was deleted. */ do_action('taxopress_after_delete_taxonomy', $data); // Used to help flush rewrite rules on init. set_transient('taxopress_flush_rewrite_rules', 'true', 5 * 60); if (isset($success)) { return 'delete_success'; } return 'delete_fail'; } /** * Add to or update our TAXOPRESS option with new data. * * * @param array $data Array of taxonomy data to update. Optional. * @return bool|string False on failure, string on success. * @internal * */ function taxopress_update_taxonomy($data = []) { //update our custom checkbox value if not checked if (!isset($data['cpt_custom_tax']['hierarchical'])) { $data['cpt_custom_tax']['hierarchical'] = 0; } if (!isset($data['cpt_custom_tax']['rewrite'])) { $data['cpt_custom_tax']['rewrite'] = 0; } if (!isset($data['cpt_custom_tax']['rewrite_withfront'])) { $data['cpt_custom_tax']['rewrite_withfront'] = 0; } if (!isset($data['cpt_custom_tax']['rewrite_hierarchical'])) { $data['cpt_custom_tax']['rewrite_hierarchical'] = 0; } if (!isset($data['cpt_custom_tax']['show_ui'])) { $data['cpt_custom_tax']['show_ui'] = 0; } if (!isset($data['cpt_custom_tax']['show_in_menu'])) { $data['cpt_custom_tax']['show_in_menu'] = 0; } if (!isset($data['cpt_custom_tax']['show_in_nav_menus'])) { $data['cpt_custom_tax']['show_in_nav_menus'] = 0; } if (!isset($data['cpt_custom_tax']['show_admin_column'])) { $data['cpt_custom_tax']['show_admin_column'] = 0; } if (!isset($data['cpt_custom_tax']['show_in_rest'])) { $data['cpt_custom_tax']['show_in_rest'] = 0; } if (!isset($data['cpt_custom_tax']['show_in_quick_edit'])) { $data['cpt_custom_tax']['show_in_quick_edit'] = 0; } if (!isset($data['cpt_custom_tax']['public'])) { $data['cpt_custom_tax']['public'] = 0; } if (!isset($data['cpt_custom_tax']['publicly_queryable'])) { $data['cpt_custom_tax']['publicly_queryable'] = 0; } if (!isset($data['cpt_custom_tax']['query_var'])) { $data['cpt_custom_tax']['query_var'] = 0; } if (!isset($data['cpt_custom_tax']['include_in_result'])) { $data['cpt_custom_tax']['include_in_result'] = 0; } /** * Fires before a taxonomy is updated to our saved options. * * * @param array $data Array of taxonomy data we are updating. */ do_action('taxopress_before_update_taxonomy', $data); // They need to provide a name. if (empty($data['cpt_custom_tax']['name'])) { return taxopress_admin_notices('error', '', false, esc_html__('Please provide a taxonomy name', 'simple-tags')); } if (!isset($data['taxonomy_external_edit'])) { // Maybe a little harsh, but we shouldn't be saving THAT frequently. delete_option("default_term_{$data['cpt_custom_tax']['name']}"); } if (!isset($data['taxonomy_external_edit'])) { if (!empty($data['tax_original']) && $data['tax_original'] !== $data['cpt_custom_tax']['name']) { if (!empty($data['update_taxonomy'])) { add_filter('taxopress_convert_taxonomy_terms', '__return_true'); } } } foreach ($data as $key => $value) { if (is_string($value)) { $data[$key] = sanitize_text_field($value); } else { array_map('sanitize_text_field', $data[$key]); } } if (false !== strpos($data['cpt_custom_tax']['name'], '\'') || false !== strpos($data['cpt_custom_tax']['name'], '\"') || false !== strpos($data['cpt_custom_tax']['rewrite_slug'], '\'') || false !== strpos($data['cpt_custom_tax']['rewrite_slug'], '\"')) { add_filter('taxopress_custom_error_message', 'taxopress_slug_has_quotes'); return 'error'; } $taxonomies = taxopress_get_taxonomy_data(); $external_taxonomies = taxopress_get_extername_taxonomy_data(); if (!isset($data['taxonomy_external_edit'])) { /** * Check if we already have a post type of that name. * * @param bool $value Assume we have no conflict by default. * @param string $value Post type slug being saved. * @param array $post_types Array of existing post types from TAXOPRESS. */ $slug_exists = apply_filters('taxopress_taxonomy_slug_exists', false, $data['cpt_custom_tax']['name'], $taxonomies); if (true === $slug_exists) { add_filter('taxopress_custom_error_message', 'taxopress_slug_matches_taxonomy'); return 'error'; } } foreach ($data['cpt_tax_labels'] as $key => $label) { if (empty($label)) { unset($data['cpt_tax_labels'][$key]); } $label = str_replace('"', '', htmlspecialchars_decode($label)); $label = htmlspecialchars($label, ENT_QUOTES); $label = trim($label); $data['cpt_tax_labels'][$key] = stripslashes_deep($label); } $label = ucwords(str_replace('_', ' ', $data['cpt_custom_tax']['name'])); if (!empty($data['cpt_custom_tax']['label'])) { $label = str_replace('"', '', htmlspecialchars_decode($data['cpt_custom_tax']['label'])); $label = htmlspecialchars(stripslashes($label), ENT_QUOTES); } $name = trim($data['cpt_custom_tax']['name']); $singular_label = ucwords(str_replace('_', ' ', $data['cpt_custom_tax']['name'])); if (!empty($data['cpt_custom_tax']['singular_label'])) { $singular_label = str_replace('"', '', htmlspecialchars_decode($data['cpt_custom_tax']['singular_label'])); $singular_label = htmlspecialchars(stripslashes($singular_label)); } $description = sanitize_textarea_field(stripslashes_deep($data['cpt_custom_tax']['description'])); $query_var_slug = trim($data['cpt_custom_tax']['query_var_slug']); $rewrite_slug = trim($data['cpt_custom_tax']['rewrite_slug']); $rest_base = trim($data['cpt_custom_tax']['rest_base']); $rest_controller_class = trim($data['cpt_custom_tax']['rest_controller_class']); $show_quickpanel_bulk = !empty($data['cpt_custom_tax']['show_in_quick_edit']) ? taxopress_disp_boolean($data['cpt_custom_tax']['show_in_quick_edit']) : ''; $default_term = trim($data['cpt_custom_tax']['default_term']); $meta_box_cb = trim($data['cpt_custom_tax']['meta_box_cb']); // We may or may not need to force a boolean false keyword. $maybe_false = strtolower(trim($data['cpt_custom_tax']['meta_box_cb'])); if ('false' === $maybe_false) { $meta_box_cb = $maybe_false; } $internal_taxonomy_edit = true; if ( isset($data['taxonomy_external_edit']) || $name === 'media_tag' ) { $internal_taxonomy_edit = false; } if ($internal_taxonomy_edit) { $taxonomies[$data['cpt_custom_tax']['name']] = [ 'name' => $name, 'label' => $label, 'singular_label' => $singular_label, 'description' => $description, 'public' => taxopress_disp_boolean($data['cpt_custom_tax']['public']), 'publicly_queryable' => taxopress_disp_boolean($data['cpt_custom_tax']['publicly_queryable']), 'include_in_result' => taxopress_disp_boolean($data['cpt_custom_tax']['include_in_result']), 'hierarchical' => taxopress_disp_boolean($data['cpt_custom_tax']['hierarchical']), 'show_ui' => taxopress_disp_boolean($data['cpt_custom_tax']['show_ui']), 'show_in_menu' => taxopress_disp_boolean($data['cpt_custom_tax']['show_in_menu']), 'show_in_nav_menus' => taxopress_disp_boolean($data['cpt_custom_tax']['show_in_nav_menus']), 'query_var' => taxopress_disp_boolean($data['cpt_custom_tax']['query_var']), 'query_var_slug' => $query_var_slug, 'rewrite' => taxopress_disp_boolean($data['cpt_custom_tax']['rewrite']), 'rewrite_slug' => $rewrite_slug, 'rewrite_withfront' => $data['cpt_custom_tax']['rewrite_withfront'], 'rewrite_hierarchical' => $data['cpt_custom_tax']['rewrite_hierarchical'], 'show_admin_column' => taxopress_disp_boolean($data['cpt_custom_tax']['show_admin_column']), 'show_in_rest' => taxopress_disp_boolean($data['cpt_custom_tax']['show_in_rest']), 'show_in_quick_edit' => $show_quickpanel_bulk, 'rest_base' => $rest_base, 'rest_controller_class' => $rest_controller_class, 'labels' => $data['cpt_tax_labels'], 'meta_box_cb' => $meta_box_cb, 'default_term' => $default_term, ]; $taxonomies[$data['cpt_custom_tax']['name']]['object_types'] = $data['cpt_post_types']; /** * Filters final data to be saved right before saving taxoomy data. * * @param array $taxonomies Array of final taxonomy data to save. * @param string $name Taxonomy slug for taxonomy being saved. */ $taxonomies = apply_filters('taxopress_pre_save_taxonomy', $taxonomies, $name); /** * Filters whether or not 3rd party options were saved successfully within taxonomy add/update. * * @param bool $value Whether or not someone else saved successfully. Default false. * @param array $taxonomies Array of our updated taxonomies data. * @param array $data Array of submitted taxonomy to update. */ if (false === ($success = apply_filters('taxopress_taxonomy_update_save', false, $taxonomies, $data))) { $success = update_option('taxopress_taxonomies', $taxonomies); } } else { $external_taxonomies[$data['cpt_custom_tax']['name']] = [ 'name' => $name, 'label' => $label, 'singular_label' => $singular_label, 'description' => $description, 'public' => taxopress_disp_boolean($data['cpt_custom_tax']['public']), 'publicly_queryable' => taxopress_disp_boolean($data['cpt_custom_tax']['publicly_queryable']), 'include_in_result' => taxopress_disp_boolean($data['cpt_custom_tax']['include_in_result']), 'hierarchical' => taxopress_disp_boolean($data['cpt_custom_tax']['hierarchical']), 'show_ui' => taxopress_disp_boolean($data['cpt_custom_tax']['show_ui']), 'show_in_menu' => taxopress_disp_boolean($data['cpt_custom_tax']['show_in_menu']), 'show_in_nav_menus' => taxopress_disp_boolean($data['cpt_custom_tax']['show_in_nav_menus']), 'query_var' => taxopress_disp_boolean($data['cpt_custom_tax']['query_var']), 'query_var_slug' => $query_var_slug, 'rewrite' => taxopress_disp_boolean($data['cpt_custom_tax']['rewrite']), 'rewrite_slug' => $rewrite_slug, 'rewrite_withfront' => $data['cpt_custom_tax']['rewrite_withfront'], 'rewrite_hierarchical' => $data['cpt_custom_tax']['rewrite_hierarchical'], 'show_admin_column' => taxopress_disp_boolean($data['cpt_custom_tax']['show_admin_column']), 'show_in_rest' => taxopress_disp_boolean($data['cpt_custom_tax']['show_in_rest']), 'show_in_quick_edit' => $show_quickpanel_bulk, 'rest_base' => $rest_base, 'rest_controller_class' => $rest_controller_class, 'labels' => $data['cpt_tax_labels'], 'meta_box_cb' => $meta_box_cb, 'default_term' => $default_term, ]; $external_taxonomies[$data['cpt_custom_tax']['name']]['object_types'] = isset($data['cpt_post_types']) ? $data['cpt_post_types'] : []; $success = update_option('taxopress_external_taxonomies', $external_taxonomies); } /** * Fires after a taxonomy is updated to our saved options. * * * @param array $data Array of taxonomy data that was updated. */ do_action('taxopress_after_update_taxonomy', $data); // Used to help flush rewrite rules on init. set_transient('taxopress_flush_rewrite_rules', 'true', 5 * 60); if (isset($success) && 'new' === $data['cpt_tax_status']) { return 'add_success'; } return 'update_success'; } /** * Return an array of names that users should not or can not use for taxonomy names. * * @return array $value Array of names that are recommended against. */ function taxopress_reserved_taxonomies() { $reserved = [ 'action', 'attachment', 'attachment_id', 'author', 'author_name', 'calendar', 'cat', 'category', 'category__and', 'category__in', 'category__not_in', 'category_name', 'comments_per_page', 'comments_popup', 'customize_messenger_channel', 'customized', 'cpage', 'day', 'debug', 'error', 'exact', 'feed', 'fields', 'hour', 'include', 'link_category', 'm', 'minute', 'monthnum', 'more', 'name', 'nav_menu', 'nonce', 'nopaging', 'offset', 'order', 'orderby', 'p', 'page', 'page_id', 'paged', 'pagename', 'pb', 'perm', 'post', 'post__in', 'post__not_in', 'post_format', 'post_mime_type', 'post_status', 'post_tag', 'post_type', 'posts', 'posts_per_archive_page', 'posts_per_page', 'preview', 'robots', 's', 'search', 'second', 'sentence', 'showposts', 'static', 'subpost', 'subpost_id', 'tag', 'tag__and', 'tag__in', 'tag__not_in', 'tag_id', 'tag_slug__and', 'tag_slug__in', 'taxonomy', 'tb', 'term', 'theme', 'type', 'types', 'w', 'withcomments', 'withoutcomments', 'year', 'output', ]; /** * Filters the list of reserved post types to check against. * 3rd party plugin authors could use this to prevent duplicate post types. * * * @param array $value Array of post type slugs to forbid. */ $custom_reserved = apply_filters('taxopress_reserved_taxonomies', []); if (is_string($custom_reserved) && !empty($custom_reserved)) { $reserved[] = $custom_reserved; } elseif (is_array($custom_reserved) && !empty($custom_reserved)) { foreach ($custom_reserved as $slug) { $reserved[] = $slug; } } return $reserved; } /** * Convert taxonomies. * * @param string $original_slug Original taxonomy slug. Optional. Default empty string. * @param string $new_slug New taxonomy slug. Optional. Default empty string. * @internal * */ function taxopress_convert_taxonomy_terms($original_slug = '', $new_slug = '') { global $wpdb; $args = [ 'taxonomy' => $original_slug, 'hide_empty' => false, 'fields' => 'ids', ]; $term_ids = get_terms($args); if (is_int($term_ids)) { $term_ids = (array)$term_ids; } if (is_array($term_ids) && !empty($term_ids)) { $term_ids = implode(',', $term_ids); $query = "UPDATE `{$wpdb->term_taxonomy}` SET `taxonomy` = %s WHERE `taxonomy` = %s AND `term_id` IN ( {$term_ids} )"; $wpdb->query( $wpdb->prepare($query, $new_slug, $original_slug) ); } taxopress_delete_taxonomy($original_slug); } /** * Checks if we are trying to register an already registered taxonomy slug. * * @param bool $slug_exists Whether or not the post type slug exists. Optional. Default false. * @param string $taxonomy_slug The post type slug being saved. Optional. Default empty string. * @param array $taxonomies Array of TAXOPRESS-registered post types. Optional. * * @return bool */ function taxopress_check_existing_taxonomy_slugs($slug_exists = false, $taxonomy_slug = '', $taxonomies = []) { // If true, then we'll already have a conflict, let's not re-process. if (true === $slug_exists) { return $slug_exists; } // Check if TAXOPRESS has already registered this slug. if (array_key_exists(strtolower($taxonomy_slug), $taxonomies)) { return true; } // Check if we're registering a reserved post type slug. if (in_array($taxonomy_slug, taxopress_reserved_taxonomies())) { return true; } // Check if other plugins have registered this same slug. $public = get_taxonomies(['_builtin' => false, 'public' => true]); $private = get_taxonomies(['_builtin' => false, 'public' => false]); $registered_taxonomies = array_merge($public, $private); if (in_array($taxonomy_slug, $registered_taxonomies)) { return true; } // If we're this far, it's false. return $slug_exists; } add_filter('taxopress_taxonomy_slug_exists', 'taxopress_check_existing_taxonomy_slugs', 10, 3); /** * Handle the save and deletion of taxonomy data. */ function taxopress_process_taxonomy() { if (wp_doing_ajax()) { return; } if (!is_admin()) { return; } if (empty($_GET)) { return; } if (!isset($_GET['page'])) { return; } if ('st_taxonomies' !== $_GET['page']) { return; } if(!current_user_can('simple_tags')){ return; } if (isset($_GET['new_taxonomy'])) { if ((int)$_GET['new_taxonomy'] === 1) { add_action('admin_notices', "taxopress_add_success_message_admin_notice"); add_filter('removable_query_args', 'taxopress_filter_removable_query_args_3'); } } if (!empty($_POST) && (isset($_POST['cpt_submit']) || isset($_POST['cpt_delete']))) { $result = ''; if (isset($_POST['cpt_submit'])) { check_admin_referer('taxopress_addedit_taxonomy_nonce_action', 'taxopress_addedit_taxonomy_nonce_field'); $result = taxopress_update_taxonomy($_POST); } elseif (isset($_POST['cpt_delete'])) { check_admin_referer('taxopress_addedit_taxonomy_nonce_action', 'taxopress_addedit_taxonomy_nonce_field'); $result = taxopress_delete_taxonomy($_POST); add_filter('taxopress_taxonomy_deleted', '__return_true'); } if ($result && is_callable("taxopress_{$result}_admin_notice")) { if($result === 'add_success'){ taxopress_add_success_admin_notice(); }else{ add_action('admin_notices', "taxopress_{$result}_admin_notice"); } } if (isset($_POST['cpt_delete'])) { wp_safe_redirect( add_query_arg( ['page' => 'st_taxonomies'], taxopress_admin_url('admin.php?page=st_taxonomies') ) ); exit(); } } elseif (isset($_REQUEST['action']) && $_REQUEST['action'] === 'taxopress-deactivate-taxonomy') { $nonce = sanitize_text_field($_REQUEST['_wpnonce']); if (wp_verify_nonce($nonce, 'taxonomy-action-request-nonce')) { taxopress_deactivate_taxonomy(sanitize_text_field($_REQUEST['taxonomy'])); add_action('admin_notices', "taxopress_deactivated_admin_notice"); } add_filter('removable_query_args', 'taxopress_filter_removable_query_args'); } elseif (isset($_REQUEST['action']) && $_REQUEST['action'] === 'taxopress-reactivate-taxonomy') { $nonce = sanitize_text_field($_REQUEST['_wpnonce']); if (wp_verify_nonce($nonce, 'taxonomy-action-request-nonce')) { taxopress_activate_taxonomy(sanitize_text_field($_REQUEST['taxonomy'])); add_action('admin_notices', "taxopress_activated_admin_notice"); } add_filter('removable_query_args', 'taxopress_filter_removable_query_args'); } elseif (isset($_REQUEST['action']) && $_REQUEST['action'] === 'taxopress-delete-taxonomy') { $nonce = sanitize_text_field($_REQUEST['_wpnonce']); if (wp_verify_nonce($nonce, 'taxonomy-action-request-nonce')) { taxopress_action_delete_taxonomy(sanitize_text_field($_REQUEST['taxonomy'])); } add_filter('removable_query_args', 'taxopress_filter_removable_query_args'); } elseif (isset($_REQUEST['action2']) && $_REQUEST['action2'] === 'taxopress-reactivate-taxonomy') { $nonce = sanitize_text_field($_REQUEST['_wpnonce']); if (wp_verify_nonce($nonce, 'taxonomy-action-request-nonce')) { taxopress_activate_taxonomy(sanitize_text_field($_REQUEST['taxonomy'])); add_action('admin_notices', "taxopress_activated_admin_notice"); } add_filter('removable_query_args', 'taxopress_filter_removable_query_args_2'); } elseif (isset($_REQUEST['action2']) && $_REQUEST['action2'] === 'taxopress-deactivate-taxonomy') { $nonce = sanitize_text_field($_REQUEST['_wpnonce']); if (wp_verify_nonce($nonce, 'taxonomy-action-request-nonce')) { taxopress_deactivate_taxonomy(sanitize_text_field($_REQUEST['taxonomy'])); add_action('admin_notices', "taxopress_deactivated_admin_notice"); } add_filter('removable_query_args', 'taxopress_filter_removable_query_args_2'); } } /** * Handle the conversion of taxonomy terms. * * This function came to be because we needed to convert AFTER registration. */ function taxopress_do_convert_taxonomy_terms() { /** * Whether or not to convert taxonomy terms. * * @param bool $value Whether or not to convert. */ if (apply_filters('taxopress_convert_taxonomy_terms', false)) { check_admin_referer('taxopress_addedit_taxonomy_nonce_action', 'taxopress_addedit_taxonomy_nonce_field'); taxopress_convert_taxonomy_terms(sanitize_text_field($_POST['tax_original']), sanitize_text_field($_POST['cpt_custom_tax']['name'])); } } /** * Handles slug_exist checks for cases of editing an existing taxonomy. * * @param bool $slug_exists Current status for exist checks. * @param string $taxonomy_slug Taxonomy slug being processed. * @param array $taxonomies TAXOPRESS taxonomies. * @return bool */ function taxopress_updated_taxonomy_slug_exists($slug_exists, $taxonomy_slug = '', $taxonomies = []) { if ( (!empty($_POST['cpt_tax_status']) && 'edit' === $_POST['cpt_tax_status']) && !in_array($taxonomy_slug, taxopress_reserved_taxonomies(), true) && (!empty($_POST['tax_original']) && $taxonomy_slug === $_POST['tax_original']) ) { $slug_exists = false; } return $slug_exists; } add_filter('taxopress_taxonomy_slug_exists', 'taxopress_updated_taxonomy_slug_exists', 11, 3); /** * Return boolean status depending on passed in value. * * @param mixed $bool_text text to compare to typical boolean values. * @return bool Which bool value the passed in value was. */ function get_taxopress_disp_boolean($bool_text) { $bool_text = (string)$bool_text; if (empty($bool_text) || '0' === $bool_text || 'false' === $bool_text) { return false; } return true; } /** * Return string versions of boolean values. * * @param string $bool_text String boolean value. * @return string standardized boolean text. */ function taxopress_disp_boolean($bool_text) { $bool_text = (string)$bool_text; if (empty($bool_text) || '0' === $bool_text || 'false' === $bool_text) { return 'false'; } return 'true'; } /** * Conditionally flushes rewrite rules if we have reason to. */ function taxopress_flush_rewrite_rules() { if (wp_doing_ajax()) { return; } /* * Wise men say that you should not do flush_rewrite_rules on init or admin_init. Due to the nature of our plugin * and how new post types or taxonomies can suddenly be introduced, we need to...potentially. For this, * we rely on a short lived transient. Only 5 minutes life span. If it exists, we do a soft flush before * deleting the transient to prevent subsequent flushes. The only times the transient gets created, is if * post types or taxonomies are created, updated, deleted, or imported. Any other time and this condition * should not be met. */ if ('true' === ($flush_it = get_transient('taxopress_flush_rewrite_rules'))) { flush_rewrite_rules(false); // So we only run this once. delete_transient('taxopress_flush_rewrite_rules'); } } /** * Return the current action being done within TAXOPRESS context. * * @return string Current action being done by TAXOPRESS */ function taxopress_get_current_action() { $current_action = ''; if (!empty($_GET) && isset($_GET['action'])) { $current_action .= esc_textarea(sanitize_text_field($_GET['action'])); } return $current_action; } /** * Return an array of all taxonomy slugs from Custom Post Type UI. * * @return array TAXOPRESS taxonomy slugs. */ function taxopress_get_taxonomy_slugs() { $taxonomies = get_option('taxopress_taxonomies'); if (!empty($taxonomies)) { return array_keys($taxonomies); } return []; } /** * Return the appropriate admin URL depending on our context. * * @param string $path URL path. * @return string */ function taxopress_admin_url($path) { if (is_multisite() && is_network_admin()) { return network_admin_url($path); } return admin_url($path); } /** * Construct action tag for `