$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 `
` tag. * * @param object|string $ui TAXOPRESS Admin UI instance. Optional. Default empty string. * @return string */ function taxopress_get_post_form_action($ui = '') { /** * Filters the string to be used in an `action=""` attribute. */ return apply_filters('taxopress_post_form_action', '', $ui); } /** * Display action tag for `` tag. * * @param object $ui TAXOPRESS Admin UI instance. */ function taxopress_post_form_action($ui) { echo esc_attr(taxopress_get_post_form_action($ui)); } /** * Fetch our TAXOPRESS taxonomies option. * * @return mixed */ function taxopress_get_taxonomy_data() { return apply_filters('taxopress_get_taxonomy_data', get_option('taxopress_taxonomies', []), get_current_blog_id()); } /** * Fetch our TAXOPRESS taxonomies option. * * @return mixed */ function taxopress_get_extername_taxonomy_data() { return array_filter((array)apply_filters('taxopress_get_extername_taxonomy_data', get_option('taxopress_external_taxonomies', []), get_current_blog_id())); } /** * Checks if a taxonomy is already registered. * * @param string $slug Taxonomy slug to check. Optional. Default empty string. * @param array|string $data Taxonomy data being utilized. Optional. * * @return mixed */ function taxopress_get_taxonomy_exists($slug = '', $data = []) { /** * Filters the boolean value for if a taxonomy exists for 3rd parties. * * @param string $slug Taxonomy slug to check. * @param array|string $data Taxonomy data being utilized. */ return apply_filters('taxopress_get_taxonomy_exists', taxonomy_exists($slug), $data); } /** * Secondary admin notices function for use with admin_notices hook. * * Constructs admin notice HTML. * * @param string $message Message to use in admin notice. Optional. Default empty string. * @param bool $success Whether or not a success. Optional. Default true. * @return mixed */ function taxopress_admin_notices_helper($message = '', $success = true) { $class = []; $class[] = $success ? 'updated' : 'error'; $class[] = 'notice is-dismissible'; $messagewrapstart = '

'; $messagewrapend = '

'; $action = ''; /** * Filters the custom admin notice for TAXOPRESS. * * * @param string $value Complete HTML output for notice. * @param string $action Action whose message is being generated. * @param string $message The message to be displayed. * @param string $messagewrapstart Beginning wrap HTML. * @param string $messagewrapend Ending wrap HTML. */ return apply_filters('taxopress_admin_notice', $messagewrapstart . $message . $messagewrapend, $action, $message, $messagewrapstart, $messagewrapend); } /** * Grab post type or taxonomy slug from $_POST global, if available. * * @return string * @internal * */ function taxopress_get_object_from_post_global() { if (isset($_POST['cpt_custom_post_type']['name'])) { return sanitize_text_field($_POST['cpt_custom_post_type']['name']); } if (isset($_POST['cpt_custom_tax']['name'])) { return sanitize_text_field($_POST['cpt_custom_tax']['name']); } return esc_html__('Object', 'simple-tags'); } /** * Successful add callback. */ function taxopress_add_success_admin_notice() { //redirect to new taxonomy if success wp_safe_redirect( add_query_arg( [ 'page' => 'st_taxonomies', 'add' => 'taxonomy', 'action' => 'edit', 'taxopress_taxonomy' => taxopress_get_object_from_post_global(), 'new_taxonomy' => 1, ], taxopress_admin_url('admin.php') ) ); exit(); } /** * Successful add callback. */ function taxopress_add_success_message_admin_notice() { // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped echo taxopress_admin_notices_helper( sprintf( esc_html__('%s has been successfully added', 'simple-tags'), sanitize_text_field($_GET['taxopress_taxonomy']) ) ); } /** * Fail to add callback. */ function taxopress_add_fail_admin_notice() { // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped echo taxopress_admin_notices_helper( sprintf( esc_html__('%s has failed to be added', 'simple-tags'), taxopress_get_object_from_post_global() ), false ); } /** * Successful update callback. */ function taxopress_update_success_admin_notice() { // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped echo taxopress_admin_notices_helper( sprintf( esc_html__('%s has been successfully updated', 'simple-tags'), taxopress_get_object_from_post_global() ) ); } /** * Fail to update callback. */ function taxopress_update_fail_admin_notice() { // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped echo taxopress_admin_notices_helper( sprintf( esc_html__('%s has failed to be updated', 'simple-tags'), taxopress_get_object_from_post_global() ), false ); } /** * Successful delete callback. */ function taxopress_delete_success_admin_notice() { // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped echo taxopress_admin_notices_helper( sprintf( esc_html__('%s has been successfully deleted', 'simple-tags'), taxopress_get_object_from_post_global() ) ); } /** * Fail to delete callback. */ function taxopress_delete_fail_admin_notice() { // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped echo taxopress_admin_notices_helper( sprintf( esc_html__('%s has failed to be deleted', 'simple-tags'), taxopress_get_object_from_post_global() ), false ); } function taxopress_nonce_fail_admin_notice() { // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped echo taxopress_admin_notices_helper( esc_html__('Nonce failed verification', 'simple-tags'), false ); } /** * Returns error message for if trying to register existing taxonomy. * * @return string */ function taxopress_slug_matches_taxonomy() { // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped return sprintf( esc_html__('Please choose a different taxonomy name. %s is already registered.', 'simple-tags'), taxopress_get_object_from_post_global() ); } /** * Returns error message for if not providing a post type to associate taxonomy to. * * @return string */ function taxopress_empty_cpt_on_taxonomy() { return esc_html__('Please provide a post type to attach to.', 'simple-tags'); } /** * Returns error message for if trying to register post type with matching page slug. * * @return string */ function taxopress_slug_matches_page() { $slug = taxopress_get_object_from_post_global(); $matched_slug = get_page_by_path( taxopress_get_object_from_post_global() ); if ($matched_slug instanceof WP_Post) { $slug = sprintf( '%s', get_edit_post_link($matched_slug->ID), taxopress_get_object_from_post_global() ); } return sprintf( esc_html__('Please choose a different post type name. %s matches an existing page slug, which can cause conflicts.', 'simple-tags'), $slug ); } /** * Returns error message for if trying to use quotes in slugs or rewrite slugs. * * @return string */ function taxopress_slug_has_quotes() { return sprintf( esc_html__('Please do not use quotes in post type/taxonomy names or rewrite slugs', 'simple-tags'), taxopress_get_object_from_post_global() ); } /** * Error admin notice. */ function taxopress_error_admin_notice() { // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped echo taxopress_admin_notices_helper( apply_filters('taxopress_custom_error_message', ''), false ); } /** * Returns saved values for single taxonomy from TAXOPRESS settings. * * @param string $taxonomy Taxonomy to retrieve TAXOPRESS object for. * @return string */ function taxopress_get_taxopress_taxonomy_object($taxonomy = '') { $taxonomies = get_option('taxopress_taxonomies'); if (array_key_exists($taxonomy, $taxonomies)) { return $taxonomies[$taxonomy]; } return ''; } /** * Register our users' custom taxonomies. * * @internal */ function taxopress_create_custom_taxonomies() { $taxes = get_option('taxopress_taxonomies'); if (empty($taxes)) { return; } /** * Fires before the start of the taxonomy registrations. * * @param array $taxes Array of taxonomies to register. */ do_action('taxopress_pre_register_taxonomies', $taxes); if (is_array($taxes)) { foreach ($taxes as $tax) { /** * Filters whether or not to skip registration of the current iterated taxonomy. * * Dynamic part of the filter name is the chosen taxonomy slug. * * @param bool $value Whether or not to skip the taxonomy. * @param array $tax Current taxonomy being registered. */ if ((bool)apply_filters("taxopress_disable_{$tax['name']}_tax", false, $tax)) { continue; } /** * Filters whether or not to skip registration of the current iterated taxonomy. * * @param bool $value Whether or not to skip the taxonomy. * @param array $tax Current taxonomy being registered. */ if ((bool)apply_filters('taxopress_disable_tax', false, $tax)) { continue; } taxopress_register_single_taxonomy($tax); } } /** * Fires after the completion of the taxonomy registrations. * * @param array $taxes Array of taxonomies registered. */ do_action('taxopress_post_register_taxonomies', $taxes); } /** * Helper function to register the actual taxonomy. * * @param array $taxonomy Taxonomy array to register. Optional. * @return null Result of register_taxonomy. * @internal * */ function taxopress_register_single_taxonomy($taxonomy = []) { $labels = [ 'name' => $taxonomy['label'], 'singular_name' => $taxonomy['singular_label'], ]; $description = ''; if (!empty($taxonomy['description'])) { $description = $taxonomy['description']; } $preserved = taxopress_get_preserved_keys('taxonomies'); $preserved_labels = taxopress_get_preserved_labels(); foreach ($taxonomy['labels'] as $key => $label) { if (!empty($label)) { $labels[$key] = $label; } elseif (empty($label) && in_array($key, $preserved, true)) { $singular_or_plural = (in_array($key, array_keys($preserved_labels['taxonomies']['plural']))) ? 'plural' : 'singular'; $label_plurality = ('plural' === $singular_or_plural) ? $taxonomy['label'] : $taxonomy['singular_label']; $labels[$key] = sprintf($preserved_labels['taxonomies'][$singular_or_plural][$key], $label_plurality); } } $rewrite = get_taxopress_disp_boolean($taxonomy['rewrite']); if (false !== get_taxopress_disp_boolean($taxonomy['rewrite'])) { $rewrite = []; $rewrite['slug'] = !empty($taxonomy['rewrite_slug']) ? $taxonomy['rewrite_slug'] : $taxonomy['name']; $rewrite['with_front'] = true; if (isset($taxonomy['rewrite_withfront'])) { $rewrite['with_front'] = ('false' === taxopress_disp_boolean($taxonomy['rewrite_withfront'])) ? false : true; } $rewrite['hierarchical'] = false; if (isset($taxonomy['rewrite_hierarchical'])) { $rewrite['hierarchical'] = ('true' === taxopress_disp_boolean($taxonomy['rewrite_hierarchical'])) ? true : false; } } if (in_array($taxonomy['query_var'], ['true', 'false', '0', '1'], true)) { $taxonomy['query_var'] = get_taxopress_disp_boolean($taxonomy['query_var']); } if (true === $taxonomy['query_var'] && !empty($taxonomy['query_var_slug'])) { $taxonomy['query_var'] = $taxonomy['query_var_slug']; } $public = (!empty($taxonomy['public']) && false === get_taxopress_disp_boolean($taxonomy['public'])) ? false : true; $publicly_queryable = (!empty($taxonomy['publicly_queryable']) && false === get_taxopress_disp_boolean($taxonomy['publicly_queryable'])) ? false : true; if (empty($taxonomy['publicly_queryable'])) { $publicly_queryable = $public; } $show_admin_column = (!empty($taxonomy['show_admin_column']) && false !== get_taxopress_disp_boolean($taxonomy['show_admin_column'])) ? true : false; $show_in_menu = (!empty($taxonomy['show_in_menu']) && false !== get_taxopress_disp_boolean($taxonomy['show_in_menu'])) ? true : false; if (empty($taxonomy['show_in_menu'])) { $show_in_menu = get_taxopress_disp_boolean($taxonomy['show_ui']); } $show_in_nav_menus = (!empty($taxonomy['show_in_nav_menus']) && false !== get_taxopress_disp_boolean($taxonomy['show_in_nav_menus'])) ? true : false; if (empty($taxonomy['show_in_nav_menus'])) { $show_in_nav_menus = $public; } $show_in_rest = (!empty($taxonomy['show_in_rest']) && false !== get_taxopress_disp_boolean($taxonomy['show_in_rest'])) ? true : false; $show_in_quick_edit = (!empty($taxonomy['show_in_quick_edit']) && false !== get_taxopress_disp_boolean($taxonomy['show_in_quick_edit'])) ? true : false; $rest_base = null; if (!empty($taxonomy['rest_base'])) { $rest_base = $taxonomy['rest_base']; } $rest_controller_class = null; if (!empty($post_type['rest_controller_class'])) { $rest_controller_class = $post_type['rest_controller_class']; } $meta_box_cb = null; if (!empty($taxonomy['meta_box_cb'])) { $meta_box_cb = (false !== get_taxopress_disp_boolean($taxonomy['meta_box_cb'])) ? $taxonomy['meta_box_cb'] : false; } $default_term = null; if (!empty($taxonomy['default_term'])) { $term_parts = explode(',', $taxonomy['default_term']); if (!empty($term_parts[0])) { $default_term['name'] = trim($term_parts[0]); } if (!empty($term_parts[1])) { $default_term['slug'] = trim($term_parts[1]); } if (!empty($term_parts[2])) { $default_term['description'] = trim($term_parts[2]); } } $args = [ 'labels' => $labels, 'label' => $taxonomy['label'], 'description' => $description, 'public' => $public, 'publicly_queryable' => $publicly_queryable, 'hierarchical' => get_taxopress_disp_boolean($taxonomy['hierarchical']), 'show_ui' => get_taxopress_disp_boolean($taxonomy['show_ui']), 'show_in_menu' => $show_in_menu, 'show_in_nav_menus' => $show_in_nav_menus, 'query_var' => $taxonomy['query_var'], 'rewrite' => $rewrite, 'show_admin_column' => $show_admin_column, 'show_in_rest' => $show_in_rest, 'rest_base' => $rest_base, 'rest_controller_class' => $rest_controller_class, 'show_in_quick_edit' => $show_in_quick_edit, 'meta_box_cb' => $meta_box_cb, 'default_term' => $default_term, ]; $object_type = !empty($taxonomy['object_types']) ? $taxonomy['object_types'] : ''; /** * Filters the arguments used for a taxonomy right before registering. * * @param array $args Array of arguments to use for registering taxonomy. * @param string $value Taxonomy slug to be registered. * @param array $taxonomy Original passed in values for taxonomy. * @param array $object_type Array of chosen post types for the taxonomy. */ $args = apply_filters('taxopress_pre_register_taxonomy', $args, $taxonomy['name'], $taxonomy, $object_type); return register_taxonomy($taxonomy['name'], $object_type, $args); } /** * Return a notice based on conditions. * * @param string $action The type of action that occurred. Optional. Default empty string. * @param string $object_type Whether it's from a post type or taxonomy. Optional. Default empty string. * @param bool $success Whether the action succeeded or not. Optional. Default true. * @param string $custom Custom message if necessary. Optional. Default empty string. * @return bool|string false on no message, else HTML div with our notice message. */ function taxopress_admin_notices($action = '', $object_type = '', $success = true, $custom = '') { $class = []; $class[] = $success ? 'updated' : 'error'; $class[] = 'notice is-dismissible'; $object_type = esc_attr($object_type); $messagewrapstart = '

'; $message = ''; $messagewrapend = '

'; if ('add' === $action) { if ($success) { $message .= sprintf(__('%s has been successfully added', 'simple-tags'), $object_type); } else { $message .= sprintf(__('%s has failed to be added', 'simple-tags'), $object_type); } } elseif ('update' === $action) { if ($success) { $message .= sprintf(__('%s has been successfully updated', 'simple-tags'), $object_type); } else { $message .= sprintf(__('%s has failed to be updated', 'simple-tags'), $object_type); } } elseif ('delete' === $action) { if ($success) { $message .= sprintf(__('%s has been successfully deleted', 'simple-tags'), $object_type); } else { $message .= sprintf(__('%s has failed to be deleted', 'simple-tags'), $object_type); } } elseif ('import' === $action) { if ($success) { $message .= sprintf(__('%s has been successfully imported', 'simple-tags'), $object_type); } else { $message .= sprintf(__('%s has failed to be imported', 'simple-tags'), $object_type); } } elseif ('error' === $action) { if (!empty($custom)) { $message = $custom; } } if ($message) { /** * Filters the custom admin notice for TAXOPRESS. * * @param string $value Complete HTML output for notice. * @param string $action Action whose message is being generated. * @param string $message The message to be displayed. * @param string $messagewrapstart Beginning wrap HTML. * @param string $messagewrapend Ending wrap HTML. */ return apply_filters('taxopress_admin_notice', $messagewrapstart . $message . $messagewrapend, $action, $message, $messagewrapstart, $messagewrapend); } return false; } /** * Return array of keys needing preserved. * * @param string $type Type to return. Either 'post_types' or 'taxonomies'. Optional. Default empty string. * @return array Array of keys needing preservered for the requested type. */ function taxopress_get_preserved_keys($type = '') { $preserved_labels = [ 'post_types' => [ 'add_new_item', 'edit_item', 'new_item', 'view_item', 'view_items', 'all_items', 'search_items', 'not_found', 'not_found_in_trash', ], 'taxonomies' => [ 'search_items', 'popular_items', 'all_items', 'parent_item', 'parent_item_colon', 'edit_item', 'update_item', 'add_new_item', 'new_item_name', 'separate_items_with_commas', 'add_or_remove_items', 'choose_from_most_used', ], ]; return !empty($type) ? $preserved_labels[$type] : []; } /** * Return label for the requested type and label key. * * @param string $type Type to return. Either 'post_types' or 'taxonomies'. Optional. Default empty string. * @param string $key Requested label key. Optional. Default empty string. * @param string $plural Plural verbiage for the requested label and type. Optional. Default empty string. * @param string $singular Singular verbiage for the requested label and type. Optional. Default empty string. * @return string Internationalized default label. * @deprecated * */ function taxopress_get_preserved_label($type = '', $key = '', $plural = '', $singular = '') { $preserved_labels = [ 'post_types' => [ 'add_new_item' => sprintf(__('Add new %s', 'simple-tags'), $singular), 'edit_item' => sprintf(__('Edit %s', 'simple-tags'), $singular), 'new_item' => sprintf(__('New %s', 'simple-tags'), $singular), 'view_item' => sprintf(__('View %s', 'simple-tags'), $singular), 'view_items' => sprintf(__('View %s', 'simple-tags'), $plural), 'all_items' => sprintf(__('All %s', 'simple-tags'), $plural), 'search_items' => sprintf(__('Search %s', 'simple-tags'), $plural), 'not_found' => sprintf(__('No %s found.', 'simple-tags'), $plural), 'not_found_in_trash' => sprintf(__('No %s found in trash.', 'simple-tags'), $plural), ], 'taxonomies' => [ 'search_items' => sprintf(__('Search %s', 'simple-tags'), $plural), 'popular_items' => sprintf(__('Popular %s', 'simple-tags'), $plural), 'all_items' => sprintf(__('All %s', 'simple-tags'), $plural), 'parent_item' => sprintf(__('Parent %s', 'simple-tags'), $singular), 'parent_item_colon' => sprintf(__('Parent %s:', 'simple-tags'), $singular), 'edit_item' => sprintf(__('Edit %s', 'simple-tags'), $singular), 'update_item' => sprintf(__('Update %s', 'simple-tags'), $singular), 'add_new_item' => sprintf(__('Add new %s', 'simple-tags'), $singular), 'new_item_name' => sprintf(__('New %s name', 'simple-tags'), $singular), 'separate_items_with_commas' => sprintf(__('Separate %s with commas', 'simple-tags'), $plural), 'add_or_remove_items' => sprintf(__('Add or remove %s', 'simple-tags'), $plural), 'choose_from_most_used' => sprintf(__('Choose from the most used %s', 'simple-tags'), $plural), ], ]; return $preserved_labels[$type][$key]; } /** * Returns an array of translated labels, ready for use with sprintf(). * * Replacement for taxopress_get_preserved_label for the sake of performance. * * @return array */ function taxopress_get_preserved_labels() { return [ 'post_types' => [ 'singular' => [ 'add_new_item' => esc_html__('Add new %s', 'simple-tags'), 'edit_item' => esc_html__('Edit %s', 'simple-tags'), 'new_item' => esc_html__('New %s', 'simple-tags'), 'view_item' => esc_html__('View %s', 'simple-tags'), ], 'plural' => [ 'view_items' => esc_html__('View %s', 'simple-tags'), 'all_items' => esc_html__('All %s', 'simple-tags'), 'search_items' => esc_html__('Search %s', 'simple-tags'), 'not_found' => esc_html__('No %s found.', 'simple-tags'), 'not_found_in_trash' => esc_html__('No %s found in trash.', 'simple-tags'), ], ], 'taxonomies' => [ 'singular' => [ 'parent_item' => esc_html__('Parent %s', 'simple-tags'), 'parent_item_colon' => esc_html__('Parent %s:', 'simple-tags'), 'edit_item' => esc_html__('Edit %s', 'simple-tags'), 'update_item' => esc_html__('Update %s', 'simple-tags'), 'add_new_item' => esc_html__('Add new %s', 'simple-tags'), 'new_item_name' => esc_html__('New %s name', 'simple-tags'), ], 'plural' => [ 'search_items' => esc_html__('Search %s', 'simple-tags'), 'popular_items' => esc_html__('Popular %s', 'simple-tags'), 'all_items' => esc_html__('All %s', 'simple-tags'), 'separate_items_with_commas' => esc_html__('Separate %s with commas', 'simple-tags'), 'add_or_remove_items' => esc_html__('Add or remove %s', 'simple-tags'), 'choose_from_most_used' => esc_html__('Choose from the most used %s', 'simple-tags'), ], ], ]; } function get_all_taxopress_taxonomies_request() { $category = get_taxonomies( ['name' => 'category'], 'objects'); $post_tag = get_taxonomies( ['name' => 'post_tag'], 'objects'); $public = get_taxonomies([ '_builtin' => false, 'public' => true, ], 'objects'); $private = get_taxonomies([ '_builtin' => false, 'public' => false, ], 'objects'); if( !array_key_exists('category', $public) && !array_key_exists('category', $public) ){ $public = array_merge($category, $public); } if( !array_key_exists('post_tag', $public) && !array_key_exists('post_tag', $public) ){ $public = array_merge($post_tag, $public); } if ( isset($_GET['taxonomy_type']) && $_GET['taxonomy_type'] === 'all' ) { $registered_taxonomies = array_merge($public, $private); }elseif ( isset($_GET['taxonomy_type']) && $_GET['taxonomy_type'] === 'private' ) { $registered_taxonomies = $private; }else{ $registered_taxonomies = $public; } return $registered_taxonomies; } function get_all_taxopress_taxonomies() { $category = get_taxonomies( ['name' => 'category'], 'objects'); $post_tag = get_taxonomies( ['name' => 'post_tag'], 'objects'); $public = get_taxonomies([ '_builtin' => false, 'public' => true, ], 'objects'); $private = get_taxonomies([ '_builtin' => false, 'public' => false, ], 'objects'); $registered_taxonomies = array_merge($category, $post_tag, $public, $private); return $registered_taxonomies; } function get_all_taxopress_public_taxonomies() { $category = get_taxonomies( ['name' => 'category'], 'objects'); $post_tag = get_taxonomies( ['name' => 'post_tag'], 'objects'); $public = get_taxonomies([ '_builtin' => false, 'public' => true, ], 'objects'); $registered_taxonomies = array_merge($category, $post_tag, $public); return $registered_taxonomies; } /** * Return an array of all deactivated taxonomy. * * @return array TAXOPRESS taxonomy. */ function taxopress_get_deactivated_taxonomy() { $taxonomies = get_option('taxopress_deactivated_taxonomies'); if (!empty($taxonomies)) { return (array)$taxonomies; } return []; } /** * None callback. */ function taxopress_noaction_admin_notice() { // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped echo taxopress_admin_notices_helper(esc_html__('Kindly select an action in bulk action dropdown!', 'simple-tags'), false); } /** * None callback. */ function taxopress_none_admin_notice() { // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped echo taxopress_admin_notices_helper(esc_html__('Kindly select atleast one taxonomy to proceed', 'simple-tags'), false); } /** * Deactivated callback. */ function taxopress_deactivated_admin_notice() { // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped echo taxopress_admin_notices_helper(esc_html__('Taxonomy has been successfully deactivated', 'simple-tags')); } /** * Activated callback. */ function taxopress_activated_admin_notice() { // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped echo taxopress_admin_notices_helper(esc_html__('Taxonomy has been successfully activated', 'simple-tags')); } /** * Delete callback. */ function taxopress_taxdeleted_admin_notice() { // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped echo taxopress_admin_notices_helper(esc_html__('Taxonomy has been successfully deleted', 'simple-tags')); } /** * Deactivated taxonomy. * * @return array TAXOPRESS taxonomy. */ function taxopress_deactivate_taxonomy($term_object) { $all_taxonomies = (array)get_option('taxopress_deactivated_taxonomies'); $all_taxonomies[] = $term_object; $all_taxonomies = array_unique(array_filter($all_taxonomies)); $success = update_option('taxopress_deactivated_taxonomies', $all_taxonomies); } /** * Activate taxonomy. * * @return array TAXOPRESS taxonomy. */ function taxopress_activate_taxonomy($term_object) { $all_taxonomies = (array)get_option('taxopress_deactivated_taxonomies'); if (($key = array_search($term_object, $all_taxonomies)) !== false) { unset($all_taxonomies[$key]); $success = update_option('taxopress_deactivated_taxonomies', $all_taxonomies); } } /** * Fetch our TAXOPRESS disabled taxonomies option. * * @return mixed */ function taxopress_get_deactivated_taxonomy_data() { return apply_filters('taxopress_get_deactivated_taxonomy_data', get_option('taxopress_deactivated_taxonomies', []), get_current_blog_id()); } /** * Filters the list of query arguments which get removed from admin area URLs in WordPress. * * @link https://core.trac.wordpress.org/ticket/23367 * * @param string[] $args Array of removable query arguments. * @return string[] Updated array of removable query arguments. */ function taxopress_filter_removable_query_args(array $args) { return array_merge($args, [ 'action', 'taxonomy', '_wpnonce', ]); } /** * Filters the list of query arguments which get removed from admin area URLs in WordPress. * * @link https://core.trac.wordpress.org/ticket/23367 * * @param string[] $args Array of removable query arguments. * @return string[] Updated array of removable query arguments. */ function taxopress_filter_removable_query_args_2(array $args) { return array_merge($args, [ 'action2', 'taxonomy', '_wpnonce', ]); } /** * Filters the list of query arguments which get removed from admin area URLs in WordPress. * * @link https://core.trac.wordpress.org/ticket/23367 * * @param string[] $args Array of removable query arguments. * @return string[] Updated array of removable query arguments. */ function taxopress_filter_removable_query_args_3(array $args) { return array_merge($args, [ 'new_taxonomy', ]); } /** * Delete our custom taxonomy from the array of taxonomies. * @return bool|string False on failure, string on success. */ function taxopress_action_delete_taxonomy($term_object) { $data = [ 'cpt_custom_tax' => [ 'name' => $term_object, ], ]; // 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); } } 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)) { add_action('admin_notices', "taxopress_taxdeleted_admin_notice"); return 'delete_success'; } add_action('admin_notices', "taxopress_delete_fail_admin_notice"); return 'delete_fail'; } function unregister_tags() { $all_taxonomies = (array)get_option('taxopress_deactivated_taxonomies'); $all_taxonomies = array_unique(array_filter($all_taxonomies)); if (count($all_taxonomies) > 0) { foreach ($all_taxonomies as $taxonomy) { if (!empty($_GET) && isset($_GET['page']) && 'st_taxonomies' == $_GET['page']) { $remove_current_taxonomy = $taxonomy; add_action('admin_menu', 'taxopress_remove_taxonomy_from_menus'); } else { taxopress_unregister_taxonomy($taxonomy); } } } } // Remove menu function taxopress_remove_taxonomy_from_menus() { global $remove_current_taxonomy; remove_menu_page('edit-tags.php?taxonomy=post_tag'); } function taxopress_unregister_taxonomy($taxonomy) { if (!taxonomy_exists($taxonomy)) { return new WP_Error('invalid_taxonomy', esc_html__('Invalid taxonomy.')); } $taxonomy_object = get_taxonomy($taxonomy); // Do not allow unregistering internal taxonomies. /*if ( $taxonomy_object->_builtin ) { return new WP_Error( 'invalid_taxonomy', esc_html__( 'Unregistering a built-in taxonomy is not allowed.' ) ); }*/ global $wp_taxonomies; $taxonomy_object->remove_rewrite_rules(); $taxonomy_object->remove_hooks(); // Remove custom taxonomy default term option. if (!empty($taxonomy_object->default_term)) { delete_option('default_term_' . $taxonomy_object->name); } // Remove the taxonomy. unset($wp_taxonomies[$taxonomy]); /** * Fires after a taxonomy is unregistered. * * @param string $taxonomy Taxonomy name. */ do_action('unregistered_taxonomy', $taxonomy); return true; } function taxopress_convert_external_taxonomy($taxonomy_object, $request_tax) { if (array_key_exists($request_tax, taxopress_get_extername_taxonomy_data())) { return taxopress_get_extername_taxonomy_data()[$request_tax]; } $taxonomy_data = (array)$taxonomy_object; foreach ($taxonomy_data as $key => $value) { //change label to array if ($key === 'labels') { $taxonomy_data[$key] = (array)$value; } //change cap to array if ($key === 'cap') { $taxonomy_data[$key] = (array)$value; } //change default terms to strings if ($key === 'default_term') { if (is_array($value) && count($value) > 0) { $taxonomy_data[$key] = join(',', array_filter($value)); } } //set query var value if not empty if ($key === 'query_var') { if (empty(trim($value))) { $taxonomy_data['query_var'] = 'false'; $taxonomy_data['query_var_slug'] = ''; } else { $taxonomy_data['query_var'] = 'true'; $taxonomy_data['query_var_slug'] = $value; } } //set rewrite if ($key === 'rewrite') { if (!empty($value) && is_array($value)) { if (count($value) > 0) { foreach ($value as $holdkey => $holdvalue) { if ($holdkey === 'with_front') { $taxonomy_data['rewrite_withfront'] = is_bool($holdvalue) ? taxopress_disp_boolean($holdvalue) : $holdvalue; } else { $taxonomy_data[$key . '_' . $holdkey] = is_bool($holdvalue) ? taxopress_disp_boolean($holdvalue) : $holdvalue; } } } $taxonomy_data[$key] = (count($value) > 0) ? 'true' : 'false'; } else { $taxonomy_data[$key] = 'false'; $taxonomy_data['rewrite_hierarchical'] = ''; $taxonomy_data['rewrite_withfront'] = ''; } } //dispose bool value if (is_bool($value)) { $taxonomy_data[$key] = taxopress_disp_boolean($value); } } //add singular label $taxonomy_data['singular_label'] = $taxonomy_data['labels']['singular_name']; //add object terms $taxonomy_data['object_types'] = $taxonomy_data['object_type']; return $taxonomy_data; } /** * Register our users' custom taxonomies. * * @internal */ function taxopress_recreate_custom_taxonomies() { $taxes = taxopress_get_extername_taxonomy_data(); if (empty($taxes)) { return; } /** * Fires before the start of the taxonomy registrations. * * @param array $taxes Array of taxonomies to register. */ do_action('taxopress_pre_register_taxonomies', $taxes); if (is_array($taxes)) { foreach ($taxes as $tax) { if ($tax['name'] === 'media_tag' && (int)get_option('taxopress_media_tag_deleted') > 0) { continue; } taxopress_re_register_single_taxonomy($tax); } } /** * Fires after the completion of the taxonomy registrations. * * @param array $taxes Array of taxonomies registered. */ do_action('taxopress_post_register_taxonomies', $taxes); } /** * Helper function to register the actual taxonomy. * * @param array $taxonomy Taxonomy array to register. Optional. * @return null Result of register_taxonomy. * @internal * */ function taxopress_re_register_single_taxonomy($taxonomy) { $labels = [ 'name' => $taxonomy['label'], 'singular_name' => $taxonomy['singular_label'], ]; $description = ''; if (!empty($taxonomy['description'])) { $description = $taxonomy['description']; } $preserved = taxopress_get_preserved_keys('taxonomies'); $preserved_labels = taxopress_get_preserved_labels(); foreach ($taxonomy['labels'] as $key => $label) { if (!empty($label)) { $labels[$key] = $label; } elseif (empty($label) && in_array($key, $preserved, true)) { $singular_or_plural = (in_array($key, array_keys($preserved_labels['taxonomies']['plural']))) ? 'plural' : 'singular'; $label_plurality = ('plural' === $singular_or_plural) ? $taxonomy['label'] : $taxonomy['singular_label']; $labels[$key] = sprintf($preserved_labels['taxonomies'][$singular_or_plural][$key], $label_plurality); } } $rewrite = get_taxopress_disp_boolean($taxonomy['rewrite']); if (false !== get_taxopress_disp_boolean($taxonomy['rewrite'])) { $rewrite = []; $rewrite['slug'] = !empty($taxonomy['rewrite_slug']) ? $taxonomy['rewrite_slug'] : $taxonomy['name']; $rewrite['with_front'] = true; if (isset($taxonomy['rewrite_withfront'])) { $rewrite['with_front'] = ('false' === taxopress_disp_boolean($taxonomy['rewrite_withfront'])) ? false : true; } $rewrite['hierarchical'] = false; if (isset($taxonomy['rewrite_hierarchical'])) { $rewrite['hierarchical'] = ('true' === taxopress_disp_boolean($taxonomy['rewrite_hierarchical'])) ? true : false; } } if (in_array($taxonomy['query_var'], ['true', 'false', '0', '1'], true)) { $taxonomy['query_var'] = get_taxopress_disp_boolean($taxonomy['query_var']); } if (true === $taxonomy['query_var'] && !empty($taxonomy['query_var_slug'])) { $taxonomy['query_var'] = $taxonomy['query_var_slug']; } $public = (!empty($taxonomy['public']) && false === get_taxopress_disp_boolean($taxonomy['public'])) ? false : true; $publicly_queryable = (!empty($taxonomy['publicly_queryable']) && false === get_taxopress_disp_boolean($taxonomy['publicly_queryable'])) ? false : true; if (empty($taxonomy['publicly_queryable'])) { $publicly_queryable = $public; } $show_admin_column = (!empty($taxonomy['show_admin_column']) && false !== get_taxopress_disp_boolean($taxonomy['show_admin_column'])) ? true : false; $show_in_menu = (!empty($taxonomy['show_in_menu']) && false !== get_taxopress_disp_boolean($taxonomy['show_in_menu'])) ? true : false; if (empty($taxonomy['show_in_menu'])) { $show_in_menu = get_taxopress_disp_boolean($taxonomy['show_ui']); } $show_in_nav_menus = (!empty($taxonomy['show_in_nav_menus']) && false !== get_taxopress_disp_boolean($taxonomy['show_in_nav_menus'])) ? true : false; if (empty($taxonomy['show_in_nav_menus'])) { $show_in_nav_menus = $public; } $show_in_rest = (!empty($taxonomy['show_in_rest']) && false !== get_taxopress_disp_boolean($taxonomy['show_in_rest'])) ? true : false; $show_in_quick_edit = (!empty($taxonomy['show_in_quick_edit']) && false !== get_taxopress_disp_boolean($taxonomy['show_in_quick_edit'])) ? true : false; $rest_base = null; if (!empty($taxonomy['rest_base'])) { $rest_base = $taxonomy['rest_base']; } $rest_controller_class = null; if (!empty($post_type['rest_controller_class'])) { $rest_controller_class = $post_type['rest_controller_class']; } $meta_box_cb = null; if (!empty($taxonomy['meta_box_cb'])) { $meta_box_cb = (false !== get_taxopress_disp_boolean($taxonomy['meta_box_cb'])) ? $taxonomy['meta_box_cb'] : false; } $default_term = null; if (!empty($taxonomy['default_term'])) { $term_parts = explode(',', $taxonomy['default_term']); if (!empty($term_parts[0])) { $default_term['name'] = trim($term_parts[0]); } if (!empty($term_parts[1])) { $default_term['slug'] = trim($term_parts[1]); } if (!empty($term_parts[2])) { $default_term['description'] = trim($term_parts[2]); } } $args = [ 'labels' => $labels, 'label' => $taxonomy['label'], 'description' => $description, 'public' => $public, 'publicly_queryable' => $publicly_queryable, 'hierarchical' => get_taxopress_disp_boolean($taxonomy['hierarchical']), 'show_ui' => get_taxopress_disp_boolean($taxonomy['show_ui']), 'show_in_menu' => $show_in_menu, 'show_in_nav_menus' => $show_in_nav_menus, 'query_var' => $taxonomy['query_var'], 'rewrite' => $rewrite, 'show_admin_column' => $show_admin_column, 'show_in_rest' => $show_in_rest, 'rest_base' => $rest_base, 'rest_controller_class' => $rest_controller_class, 'show_in_quick_edit' => $show_in_quick_edit, 'meta_box_cb' => $meta_box_cb, 'default_term' => $default_term, ]; $object_type = !empty($taxonomy['object_types']) ? $taxonomy['object_types'] : ''; /** * Filters the arguments used for a taxonomy right before registering. * * @param array $args Array of arguments to use for registering taxonomy. * @param string $value Taxonomy slug to be registered. * @param array $taxonomy Original passed in values for taxonomy. * @param array $object_type Array of chosen post types for the taxonomy. */ $args = apply_filters('taxopress_pre_register_taxonomy', $args, $taxonomy['name'], $taxonomy, $object_type); return register_taxonomy($taxonomy['name'], $object_type, $args); } function taxopress_show_all_cpt_in_archive_result($request_tax){ $taxonomies = taxopress_get_taxonomy_data(); $current = false; if ($request_tax && array_key_exists($request_tax, $taxonomies)) { $current = $taxonomies[$request_tax]; } elseif (taxonomy_exists($request_tax)) { //not out taxonomy $external_taxonomy = get_taxonomies(['name' => $request_tax], 'objects'); if (isset($external_taxonomy) > 0) { $current = taxopress_convert_external_taxonomy($external_taxonomy[$request_tax], $request_tax); } } $status = isset($current) && isset($current['include_in_result']) ? get_taxopress_disp_boolean($current['include_in_result']) : false; return $status; }