0
votes

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 (e.g. 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; ?>
1
Where is $values coming from? I presume that should be $attributes?FluffyKitten
Have updated to $attributes, the loop still produces duplicatesSBWT
I assumed you were getting no results because your question was very vague ("no dice so far" doesn't give any indication of what was wrong). So the problem is actually that the $filter_attributes array has duplicates? How is it working at all then because you are still using $values in your foreach loop? What is $values and how does it have the right values? I'm not sure what your code is trying to do. What are you hoping to achieve by if (in_array...) continue?FluffyKitten
thanks for your assistance, have updated to show $values is the ACF checkbox value. I'm trying to output a single instance of each attributeSBWT
You logic is all wrong. For example, What are you hoping to achieve by if (in_array...) continue? That has no effect whatsoever.FluffyKitten

1 Answers

0
votes

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. e.g.

$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 );