creocoder / yii2-nested-sets

The nested sets behavior for the Yii framework.
Other
446 stars 129 forks source link

Creating a custom tree array #74

Closed andrewmclagan closed 9 years ago

andrewmclagan commented 9 years ago

Implementing this is very easy, although using it at a practical level I'm finding difficult.

How would I create a custom nested plain array such as the following:

[
    {
        'id'        => 123,
        'name'      => 'Example',
        'value'     => 'Testing',
        'children'  => [
            {
                'id'        => 123,
                'name'      => 'Example',
                'value'     => 'Testing',
                'children'  => [],
            },
            {
                'id'        => 123,
                'name'      => 'Example',
                'value'     => 'Testing',
                'children'  => [],
            },  
        ]
    },
    {
        'id'        => 123,
        'name'      => 'Example',
        'value'     => 'Testing',
        'children'  => [
            {
                'id'        => 123,
                'name'      => 'Example',
                'value'     => 'Testing',
                'children'  => [            
                {
                    'id'        => 123,
                    'name'      => 'Example',
                    'value'     => 'Testing',
                    'children'  => [],
                }
            },

        ]
    },

];    
Mihai-P commented 9 years ago

Take a look at the examples, basically add 2 roots and start adding children to them. I just hope not all of your IDs are 123 :).

andrewmclagan commented 9 years ago

I keep trying to get this logic right but just cant seem to crack it...

public function findAllGlobalPages()
{
    $roots = ProposalPage::find()->asArray()->roots()->all();

    //echo '<pre>'; print_r($roots); exit;

    $tree = [];

    $this->buildTree($roots, $tree); 

    //echo '<pre>'; print_r($tree); exit;

    return $tree;    
}  

public function buildTree($nodes, &$tree) 
{ 
    foreach ($nodes as $node) 
    {
        $arNode = ProposalPage::findOne(['id' => $node['id']]);

        if ($arNode->children()) 
        { 
            $node['children'] = $arNode->children()->asArray()->all();  

        }
        else {
            $node['children'] = [];
        }

        $tree[] = $node;

        $this->buildTree($node['children'], $tree);
    }
}
andrewmclagan commented 9 years ago

The trait in this gist: https://gist.github.com/ptheofan/d6760ebbaf2371c75c62

solved my problem, although be aware the default attribute names have been changed, and other small modification will be needed to work with most situations.