Q:

ArrayCollection::forAll with recursion

Today I found weird behavior when using ArrayCollection::forAll method against an anonymous function with a recursion.
Preconditions:
I have a collection of Post entities. Each Post contains a collection of SocialPost entities.
Aim:
Set status for all Post and SocialPost entities to "pending".
My solution:
I thought that I could use pretty simple closure, like this:
    $setPending = function($_, StatusAwareInterface $post) use (&$setPending) {
        echo "func entry point reached\r\n";
        if ($post instanceof Post) {
            echo "This is post. SP Count: " . count($post->getSocialPosts()) . "\r\n";
            $post->getSocialPosts()->forAll($setPending);
            $status = Post::STATUS_PENDING;
        } else {
            echo "This is SP\r\n";
            $status = SocialPost::STATUS_PENDING;
        }

        $post->setStatus($status);
    };

    // $post contains 2 Post entities
    // Each Post entity contains 50+ SocialPost entities
    $posts->forAll($setPending);

Result:
But the output is very strange. It looks like forAll uses only the first item and then breaks:
func entry point reached
This is post. SP Count: 52
func entry point reached
This is SP

Does anybody sees the problem here?

A:

Let's check  ArrayCollection source
Doc says:
      * Applies the given predicate p to all elements of this collection,
      * returning true, if the predicate yields true for all elements.

This may be misleasing because what it doesn't say is that if predicate returns false, the whole function forAll return false immediately.
Let's take a look at the source:
public function forAll(Closure $p)
{
    foreach ($this->elements as $key => $element) {
        if ( ! $p($key, $element)) { // <-- here's null converted to false.
            return false;
        }
    }

    return true;
}

Your function doesn't return anything, which is null. Going further, null is converted to false, what causes forAll method to break before completing iteration over your ArrayCollection.
As a solution you should add line 
return true;

at the and of your anonymous function.
Additional note: forAll should be be understand as 

check if every element in collection matches the condition

and not 

do something for each element of collection

If you want to do this right, you should simply do foreach loop.

