Search code examples
phpcakephpcakephp-3.0cakephp-3.6

Alternative for Recursive in CakePHP 3.6.x


In CakePHP 2.x there was the recursive setting, and depending on the setting, it would go X amount of levels deep with its queries...

I took a look at the following questions, but they did not answer my question...

CakePHP 3 Fetch associated data recursive

Recursive in cakephp3?


Right now, I am attempting to recursively retrieve the following table

+----+------------+------------+------------+------------------------------------------+
| id | message_id | account_id | to_user_id | message                                  |
+----+------------+------------+------------+------------------------------------------+
|  1 |          0 | 10         |       1617 | asd a sfg sdfhgdfh  gf dgh dfghfdgh      |
|  2 |          1 | 1617       |         10 | afdkjnjdsf ndfs jfsd kjlfdgs kljgfsd jkl |
|  3 |          2 | 10         |       1617 | t5ge6h65h 6e6heh6eh6 he h e              |
|  4 |          3 | 1617       |         10 | kljnnjkl nkl njkln jkln jkl              |
|  5 |          4 | 10         |       1617 | fffffffffffffff                          |
+----+------------+------------+------------+------------------------------------------+

With the following table definitions

$this->belongsTo('Messages', [
    'foreignKey' => 'message_id',
    'joinType' => 'INNER'
]);
$this->hasMany('Replies', [
    'className' => 'Messages',
    'foreignKey' => 'message_id',
    'propertyName' => 'replies'
]);

And the following find statement

$message = $this->Messages->find('all', ['contain' => ['Replies']])->where(['Messages.id' => $id])->first();

These are my results

App\Model\Entity\Message Object
(
    [id] => 1
    [account_id] => 10
    [message] => asd a sfg sdfhgdfh  gf dgh dfghfdgh
    [message_id] => 0
    [to_user_id] => 1617
    [replies] => Array
        (
            [0] => App\Model\Entity\Message Object
                (
                    [id] => 2
                    [account_id] => 1617
                    [message] => afdkjnjdsf ndfs jfsd kjlfdgs kljgfsd jkl
                    [message_id] => 1
                    [to_user_id] => 10
                    [[new]] => 
                    [[accessible]] => Array
                        (
                            [account_id] => 1
                            [message] => 1
                            [message_id] => 1
                            [to_user_id] => 1
                            [messages] => 1
                        )

                    [[dirty]] => Array
                        (
                        )

                    [[original]] => Array
                        (
                        )

                    [[virtual]] => Array
                        (
                        )

                    [[errors]] => Array
                        (
                        )

                    [[invalid]] => Array
                        (
                        )

                    [[repository]] => Replies
                )

        )
    [[new]] => 
    [[accessible]] => Array
        (
            [account_id] => 1
            [message] => 1
            [message_id] => 1
            [to_user_id] => 1
            [messages] => 1
        )

    [[dirty]] => Array
        (
        )

    [[original]] => Array
        (
        )

    [[virtual]] => Array
        (
        )

    [[errors]] => Array
        (
        )

    [[invalid]] => Array
        (
        )

    [[repository]] => Messages
)

My question is, is how do I get the "Replies" property of the "replies" array items to be populated? ie: How do I get the second and third and so on levels of the replies to be populated within the replies?


Solution

  • You have to explicitly state exactly what you want to contain now. To get three levels of replies, this should work:

    $message = $this->Messages->find('all', [
        'contain' => ['Replies' => ['Replies' => ['Replies']]]
    ])->where(['Messages.id' => $id])->first();