Support

Account

Home Forums Backend Issues (wp-admin) Adding Taxonomies Dynamically and Removing Unwanted Ones

Solved

Adding Taxonomies Dynamically and Removing Unwanted Ones

  • My overall goal is to create taxonomies dynamically in the admin, then use those to filter results on the frontend.

    I have an options page setup with ACF with a repeater inside that I use to create the taxonomies. Here is the code for that.

    
    function add_filters() {
    
      while(has_sub_field('filters', 'option')):
    
        $filter_name = get_sub_field('filter_name'); 
        $filter_name_slug = urlFriendlyString($filter_name);
        $filter_name_underscore = urlFriendlyStringUnderscore($filter_name);
        $filter_name_plural = $filter_name . 's';
    
        // Register Taxonomies
        if(!taxonomy_exists($filter_name_underscore)){
            register_taxonomy(
                $filter_name_underscore,
                'nl_sig_weddings',
                array(
                    'label' => __($filter_name),
                    'hierarchical' => false,
                    'rewrite' => array('slug' => $filter_name_slug),
                    'show_in_menu' => false
                )
            );
        }
    
      endwhile;
    }
    
    add_action( 'init', 'add_filters');
    

    This is working fine, however the problem is when I delete one of the taxonomies from the options page I need a way to remove it along with all of the terms. So basically, get all list of all taxonomies and compare it to the fields in the options page. If a taxonomy isn’t in the options page delete it along with all of it’s terms.

    I can get an array of all taxonomies with the code below but how would I go about comparing those taxonomies to the ones in the option page and delete ones not list?

    
    $customPostTaxonomies = get_object_taxonomies('nl_sig_weddings');
    var_dump($customPostTaxonomies);
    

    Any help would be appreciated!

  • So here’s where you’re going to have a problem. If the taxonomy does not exist in the options then you’re not calling register_taxonomy() for that taxonomy. If you don’t call register_taxonomy() then the taxonomy does not exist and will not be returned by get_object_taxonomies(), and you won’t be able to delete any of it’s terms because it does not exist.

    I’ve done a search for how to delete terms in WordPress when the taxonomy is deleted and I found nothing.

    Basically, this leaves the all the term information in the DB with no way that I know of to delete it, at least not using WP functions. You’ll need to use get_taxonomies() to get a list of the registered ones and then you’ll need to use $wpdb and do queries to find out what’s in the database that isn’t registered and use db queries to delete it all.

    So this is what I’d do. I would use and acf/update_value filter when the field is saved https://www.advancedcustomfields.com/resources/acfupdate_value/. The value in the database at this point will be the old value and you can compare the old value to the new value and remove that terms for the taxonomies that no longer exist. The problem is that you can’t use ACF functions to get the existing values. Once you have a list of the ones that need to be removed you can use get_terms() and wp_delete_term() https://developer.wordpress.org/reference/functions/get_terms/ wp_delete_term(), https://codex.wordpress.org/Function_Reference/wp_delete_term

    Something like this, this code has not been checked for errors or tested. I’d backup my database before trying it.

    
    add_filter('acf/update_value/name=repeater_field_name', 'my_remove_terms');
    function my_remove_terms($value, $post_id, $field) {
      $repeater = 'filters';
      $sub_field = 'filter_name';
      $sub_field_key = 'field_123456789'; // need this to loop through value
      // get old values
      $count = intval(get_options('options_'.$repeater, 0));
      $current = array();
      for ($i=0; $i<$count; $i++) {
        $option = get_option('options_'.$repeater.'_'.$i.'_'.$sub_field, '');
        if ($value) {
          $current[$option] = $option;
        }
      } // end for
      // end get old values
      if (count($value)) {
        foreach ($value as $row) {
          $option = $row[$sub_field_key];
          if (isset($current[$option])) {
            unset($current[$option]);
          }
        } // end for
      } // end if
      // $current should have a list of the ones that need to be deleted
      if (!count($current)) {
        // nothing needs to be deleted
        return;
      }
      $args = array(
        'hide_empty' => false,
        'fields' => 'ids'
      );
      foreach ($current as $taxonomy) {
        $terms = get_terms($taxonomy, $args);
        if (count($terms)) {
          foreach ($terms as $term_id) {
            wp_delete_term($term_id, $taxonomy);
          } // end foreach term
        } // end if terms
      } // end for each tax to delete
    } // end function
    
  • Thanks for the reply! Your first paragraph is absolutely correct and I found this out a couple hours after posting this and trying a few different things!

    Thanks for the code, I will give it a shot 🙂

  • Hey John, I am trying to test out your code above, however I am running into a couple roadblocks (which I am not smart enough to figure out 🙂 )

    First, I changed acf/update_value/name=filters, which is my repeater field name.

    Then I added my sub field key, which if I am right is the data-key=”field_5702af55a084f” that is on each td that contains an input/entry on the options page.

    If I run the code now I get the following errors when I click the “Save Options” button…

    
    Warning: Missing argument 2 for my_remove_terms() in /home/evolve/public_html/neilLesson/wp-content/themes/neillesson.com/functions.php on line 403
    
    Warning: Missing argument 3 for my_remove_terms() in /home/evolve/public_html/neilLesson/wp-content/themes/neillesson.com/functions.php on line 403
    
    Fatal error: Call to undefined function get_options() in /home/evolve/public_html/neilLesson/wp-content/themes/neillesson.com/functions.php on line 408
    

    Due to the Fatal Error I tried changing get_options to get_option but then I get…

    
    
    Warning: Missing argument 2 for my_remove_terms() in /home/evolve/public_html/neilLesson/wp-content/themes/neillesson.com/functions.php on line 403
    
    Warning: Missing argument 3 for my_remove_terms() in /home/evolve/public_html/neilLesson/wp-content/themes/neillesson.com/functions.php on line 403
    
    Warning: Invalid argument supplied for foreach() in /home/evolve/public_html/neilLesson/wp-content/themes/neillesson.com/functions.php on line 418
    
    Warning: Cannot modify header information - headers already sent by (output started at /home/evolve/public_html/neilLesson/wp-content/themes/neillesson.com/functions.php:403) in /home/evolve/public_html/neilLesson/wp-includes/pluggable.php on line 1228
    

    I will keep looking into it but any help would be awesome!

  • The errors are because the add_filter statement is wrong.
    try this

    
    add_filter('acf/update_value/name=repeater_field_name', 'my_remove_terms', 10, 3);
    

    change `get_options’ to ‘get_option’, I make that mistake every time I use that function, my fingers always add that dang s

Viewing 5 posts - 1 through 5 (of 5 total)

You must be logged in to reply to this topic.