Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I've a filter attached, that allows modifying an array:

$data = apply_filters( 'wpse_example_filter', $data );

The problem is, that the data can be a single or multidimensional array:

// single:
'SINGLE' => array(
    // some data
)
// multidimensional:
'MULTI' => array(
     0 => array(
         // some data
     )
     1 => array(
         // some data
     )
)

Question: What's the easiest way to loop through the data of one of those arrays (inside my callback), without knowing if I got a single or multidimensional array and without creating another callback function?

In other words: How would I write a recursive filter callback?

share|improve this question
    
Have you tried using the array_walk_recursive function in PHP? php.net/manual/en/function.array-walk-recursive.php –  Otto Aug 31 '12 at 17:07
    
@Otto Just add an answer - upvotes are real. –  kaiser Aug 31 '12 at 17:22
    
That wasn't an answer in and of itself, I was asking for clarification. Your particular situation may not be suited to using that function, since I don't know exactly what you're trying to do with the data. –  Otto Aug 31 '12 at 17:26
    
Imagine above filter to be in some 3rd party plugin. Below array (SINGLE/MULTI) is what is inside $data. I'm then writing another plugin to modify the $data, array by array - or just a single one. –  kaiser Aug 31 '12 at 17:51

2 Answers 2

up vote 3 down vote accepted

While your answer is very interesting and I like it, I still want to post another proposal, just let you have another choice :)

IMHO, if the data contains only simple fields, like:

array(
    'name' => 'my name',
    'address' => 'my address',
    'phone' => '01234',
);

then you can use the code below:

add_filter( 'wpse63692_example_filter', 'wpse63692_example_cb' );

function wpse63692_example_cb( $data )
{
    foreach ( $data as $key => $value )
    {
        // Recursively apply filters to sub array
        if ( is_array( $value ) )
            $data[$key] = apply_filters( current_filter(), $value );
    }

    // Do something with $data

    return $data;
}
share|improve this answer
1  
+1 :) I hope you don't mind the edit. One sidenote: is_array() will also trigger sub-sub-sub-arrays and fail in this case (where one wants to not touch the sub array. –  kaiser Aug 31 '12 at 12:47
1  
I like your current_filter function! Thanks for editing for me :) –  Rilwis Aug 31 '12 at 15:56

This is what I've found so far.

The trick is, that I'm using a non existent 2nd argument named $recursive to determine if I'm in a recursive loop or not. The default value is false, so the $is_multiple loop gets triggered. I'm then passing a true to the function call, to disallow a loop through possibly present sub-sub-arrays.

The only reason why this is possible, is that the filter/action API doesn't start crying when I got more arguments for my function, than apply_filters() has.

function wpse63692_example_cb( $data, $recursive = false )
{
    $result = $data;
    if ( 1 < count( $data ) AND ! $recursive )
    {
        $result = array();
        foreach ( $data as $key => $value )
            $result[ $key ] = call_user_func( __FUNCTION__, $value, true );
    }

    return $result;
}
add_filter( 'wpse63692_example_filter', 'wpse63692_example_cb' );
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.