views:

292

answers:

5

I have a menu system that uses a drag and drop tree structure to make it easy for a user to modify. When the javascript serializes the string, it does it in the following way:

// Assume each of these items has an ID on with the respective numbers attached
Menu Item 1
  + Menu Item 2
  + Menu Item 3
     + Menu Item 4
Menu Item 5
Menu Item 6
  + Menu Item 7

This will then get serialized as:

1>2>3>>4#5#6>7

The problem with this is that there could be an arbitrary number of sublevels, which makes it difficult to unserialize. I'm using PHP server side to unserialize it but I am at a loss as to what to do.

Any suggestions welcome, even to the method of serialization, I’ll just hack the code.

+1  A: 

hmm...

http://uk2.php.net/manual/en/function.serialize.php http://uk2.php.net/manual/en/function.unserialize.php

so: $var_name = serialize( "Menu Item 1, Menu Item 2, Menu Item 3, etc...");

// do whatever

$var_name2 = unserialize($var_name);

Would that be a good method for you to use?

Dorjan
Sorry, my mistake. The menu is serialized by the javascript ready to be sent off server side.
xenon
Ah no problem, others will answer then as this method is really for PHP.
Dorjan
+3  A: 

You should look into json_encode/json_decode functions in PHP, those make interacting with Javascript really easy.

With your current serialization format you are just creating headaches for yourself.

Anti Veeranna
Thanks, I was being such an idiot. Now I know!
xenon
+1  A: 

I think you can split this string first by '#', then each split result splits by regex to exactly "number>number" so ">>" will not be there, then "number>>number" and so on.
Hope it helps.
Sorry for my english.

Alexey Ogarkov
+1  A: 

What about to serialize (instead of your string 1>2>3>>4#5#6>7) into JSON form like this:

{'1': {'2': {'3': {'4': true}}}, '5': true, '6': {'7': true}}

Then you can unserialize it using json_decode in PHP.

Thevs
+1  A: 

If you really wanted to use that format, something like this would work, but I think JSON would be much better.

<?php

$str = '1>2>3>>4#5#6>7';

preg_match_all('~([^\d]+)?([\d]+)~', $str, $matches, PREG_SET_ORDER);

//$current is the nodes from the top to the node we are at currently
$current = array();
$result = array();

foreach ($matches as $item) {
    $id = $item[2];

    if (!$item[1] || $item[1] == '#') {
        $level = 0;   
    } else {
        $level = strlen($item[1]);    
    }

    $tmp = array( 'id' => $id );

    $current[ $level ] = & $tmp;

    if ($level == 0) {
        $result[] = & $tmp;   
    } elseif (isset($current[ $level - 1 ])) {
        $parent = & $current[ $level - 1 ];
        if (!isset($parent['children'])) {
            $parent['children'] = array();   
        }
        $parent['children'][] = & $tmp;
        unset($parent);
    } 

    unset($tmp);
}

print_r($result);
Tom Haigh