Support

Account

Home Forums Front-end Issues Reverse Query ACF Term "meta"

Solved

Reverse Query ACF Term "meta"

  • Lots of threads lately asking for ACF to support term meta officially. This might actually be a use case.

    I’m trying to display a grouped <select> field where the group names are that of one Taxonomies terms, and each groups members are terms in a separate taxonomy associated with the other one via an ACF select field.

    I’ll elaborate.
    I’ve registered Taxonomy_A who’s terms are locations. I also have Taxonomy_B who’s terms are units. Each unit exists within a location so all Taxonomy_B terms have a required ACF field for choosing its parent location. This is all fine, but now I’m trying to populate a <select> where each <optgroup> is a location and its<options> are units.

    How would I get all terms of Taxonomy_B where its ACF field data equals a certain value (in this case, a location)?

  • Hi @joelstransky

    ACF save the taxonomies’ value in the wp_options table. In this case, you need to use the wpdb class.

    Here’s an example how to do it:

    // you can set the ID automatically. This is just an example
    $location_id = 99;
    
    // this is the taxonomy b's slug
    $taxonomy_slug = 'taxonomy_b';
    
    // this is the taxonomy b's parent field name
    $taxonomy_field_name = 'location_field_name';
    
    $rows = $wpdb->get_results($wpdb->prepare( 
        "
        SELECT option_name 
        FROM {$wpdb->prefix}options
        WHERE option_name LIKE %s
        AND option_value = %s
        ",
        $taxonomy_slug . '_%_' . $taxonomy_field_name,
        $location_id
    ));
    
    $unit_ids = array();
    
    foreach( $rows as $row ){
        preg_match('/^' . $taxonomy_slug . '_(\d*)_' . $taxonomy_field_name . '$/', $row->option_name, $matches);
        $unit_ids[] = $matches[1];
    }
    
    $terms = get_terms(array(
        'taxonomy' => $taxonomy_slug,
        'hide_empty' => false,
        'include' => $unit_ids,
    ));
    
    print_r($terms);

    I hope this helps 🙂

  • Thanks @James,
    It wasn’t until my drive home that I realized the lack of a wp_options api meant I was probably going to have to resort to wpdb. I’ll check it out tomorrow but this looks like exactly what I was after. Cheers.
    Sadly, this would be easier if termsmeta was adopted.

  • So I modified your solution with the intent making the value optional. I’m not very good with SQL so I doubt my use of the AND statement is the cleanest way to do that.

    
    function acf_get_terms( $args = array() ) {
      global $wpdb;
      $defaults = array(
        'taxonomy_slug'     => '',
        'acf_field_name'    => null,
        'meta_value'        => '',
      );
      $args = wp_parse_args( $args, $defaults );
    
      if ( empty($args['taxonomy_slug']) || ! taxonomy_exists( $args['taxonomy_slug'] ) || empty( $args['acf_field_name'] ) ) {
        return new WP_Error( 'invalid_option_name', __('ACF term meta names are formatted as {$term->taxonomy}_{$term->term_id}_{$field[\'name\']}.') );
      }
    
      $rows = $wpdb->get_results($wpdb->prepare(
          "
          SELECT option_name
          FROM {$wpdb->prefix}options
          WHERE option_name LIKE %s
          AND option_value LIKE %s
          ",
          $args['taxonomy_slug'] . '_%_' . $args['acf_field_name'],
          empty($args['meta_value']) ? '%' : $args['meta_value']
      ));
    
      $unit_ids = array();
    
      foreach( $rows as $row ){
          preg_match('/^' . $args['taxonomy_slug'] . '_(\d*)_' . $args['acf_field_name'] . '$/', $row->option_name, $matches);
          $unit_ids[] = $matches[1];
      }
    
      $terms = get_terms(array(
          'taxonomy' => $args['taxonomy_slug'],
          'hide_empty' => false,
          'include' => $unit_ids,
      ));
    
      return $terms;
    }
    
Viewing 4 posts - 1 through 4 (of 4 total)

The topic ‘Reverse Query ACF Term "meta"’ is closed to new replies.