Skip to content

Instantly share code, notes, and snippets.

@vjandrea
Last active December 24, 2015 16:09
Show Gist options
  • Save vjandrea/6825675 to your computer and use it in GitHub Desktop.
Save vjandrea/6825675 to your computer and use it in GitHub Desktop.
Example in procedural code for a tree parser based on an array that i'd like to implement in ClosureTable It echoes the code that should be executed once implemented.
<?php
$data = [
[ 'id' => 0 ],
[ 'id' => 1 ],
[ 'id' => 2,
'children' => [
[ 'id' => 3 ],
[ 'id' => 4,
'children' => [
[ 'id' => 5 ],
],
],
],
],
];
function createFromArray($data = array(), $parent = null)
{
$last_id = $parent;
foreach($data as $key => $value)
{
if($key == 'id' && !is_array($value))
{
$last_id = $value;
if($parent != null)
{
// A parent is set, we can perform the moves
echo '$page = Page::find('.$value.')'."\n";
echo '$page->moveTo('.$parent.')'."\n";
}
}
elseif($key == 'children' && is_array($value) && !is_null($parent))
{
// A parent is set, we parse the subtree
createFromArray($value, $last_id);
}
elseif(is_array($value) && count($value))
{
// Key is not id nor children, we're at the root of the array
createFromArray($value, $last_id);
}
}
}
createFromArray($data);
@vjandrea
Copy link
Author

vjandrea commented Oct 4, 2013

@kapooostin, thanks for the comments! The code above is simply a test of recursion, but actually i would like the function to be the most flexible we can achieve, a sort of "eat-all".
We have to consider that the id field is usually an auto_increment in the nodes model, so i would prefer a structure where the id is not specified and it's taken on the fly at the moment of the node creation, something like

$data = [
    [ 'name' => 'Root 1' , 'description' => 'Lorem ipsum...'],
    [ 'name' => 'Root 2' , 'description' => 'Donec etiam'],
    [ 'name' => 'Root 3', 'description' => 'Eiusque idem',
      'children' => [
        [ 'name'=> 'Child 1', 'description' => 'Yadayada'],
        [ 'name'=> 'Child 2', 'description' => 'Blabla'
          'children' => [
            [ 'name' => 'Grandchild 1', 'description' => 'Down under'],
          ],
        ],
      ],
    ],
  ];

In this way new nodes would be created, but if for example there's a unique constraint on one of the fields, we could check if it's already existing before trying to create a new node.
If, instead, the id is present in the array, then we take the existing nodes by id, update the eventually present fields with the values of the array and reposition them in the new structure. If an id doesn't exist, we may create a node with the rest of the fields of that node and replace the id present in the array with the new id. Every step then should be in a nice "try... catch" sandwich to avoid pitfalls.

@kapooostin
Copy link

I rarely use auto-incremented IDs, so my view is biased. But I guess at first we need the most common cases to be solved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment