简体   繁体   中英

Advanced Custom Fields (ACF) - loop through repeater checkout field and output single instance of each value

I have a WordPress page that loops through a list of products. The products are created using ACF repeater field. Each product has a one or more attributes (eg light, dark, metallic, colourful) applied using the checkbox field.

The aim is to query the checkbox repeater fields for all products on the page, see what attributes are assigned to each product on an individual basis, and output a single list for all products (stripping out duplicates).

For example, if there were ten products and between them they were tagged with four unique attributes, only the four unique attributes would be output.

I've tried creating an empty array and then looping through that. The current loop outputs duplicate values (eg light dark light dark light dark instead of light dark )

<?php if (have_rows('product')): while (have_rows('product')) : the_row(); 
    $attributes = get_sub_field_object('product_attributes'); 
    $values = $attributes['value'];  
    if($values) {
        $filter_attributes = array();
        foreach ($values as $value) {
            if (in_array($attributes, $filter_attributes)) {
                continue;
            }
        $filter_attributes[] = $attributes;
        echo $value . " ";
    } 
} endwhile; endif; ?>

There are quite a few issues with your code so we really need to start again. Based on what you've provided and without knowing exactly how your ACF repeater is set up, I think the following should work for you.

What it appears that you want to do is:

  1. Loop through all products in your repeater
  2. Get all values from your product_attributes
  3. Get the unique values across all products
  4. Display the unique values on the same line, separated by spaces

The main problem you are having is getting the unique array. There are a number of ways to do this, you chose the most complicated :)

1. Use in_array to check previous values

This is the way you are trying to do it at the moment, but you are having problems with the logic. Therefore I'd suggest option 2, but for completeness this is how you should do it:

$filter_attributes = array();

if (have_rows('product')): while (have_rows('product')) : the_row(); 
    $attributes = get_sub_field_object('product_attributes'); 
    $values = $attributes['value'];  
    if($values) {
        foreach ($values as $value) 
            if (!in_array($value, $filter_attributes)) {
                $filter_attributes[] = $value;
            }
    } 
} endwhile; endif;

/* display the values on the same line, separated by spaces */
echo implode(" ", $filter_attributes );

2. Use array_unique

The code for this is much simpler than the previous option. You save all values into an array and then at the end use array_unique ( PHP.net array_unique ). This eliminates the need for checking the existing values every time. eg

$all_attributes = array();
$filter_attributes = array();

if (have_rows('product')): while (have_rows('product')) : the_row(); 
    $attributes = get_sub_field_object('product_attributes'); 
    $values = $attributes['value'];  
    if($values) {
        foreach ($values as $value) 
            $all_attributes[] = $value; /* Save ALL values */
    } 
} endwhile; endif;

/* use array_unique to remove duplicates from the array */
$filter_attributes = array_unique ($all_attributes);
/* display the values on the same line, separated by spaces */
echo implode(" ", $filter_attributes );

3. Use the array key

If you use the value for the array key, then that will ensure each values will be unique because duplicate keys are not allowed in the array. It's slightly hack-y way, but its quick & easy :)

$filter_attributes = array();

if (have_rows('product')): while (have_rows('product')) : the_row(); 
    $attributes = get_sub_field_object('product_attributes'); 
    $values = $attributes['value'];  
    if($values) {
        foreach ($values as $value) 
            /* if  $all_attributes[$value] already exists, this will overwrite it 
               ensuring the array only has unique values */
            $all_attributes[$value] = $value;
    } 
} endwhile; endif;

/* display the values on the same line, separated by spaces */
echo implode(" ", $filter_attributes );

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM