public static function nest(array $data, $options = array())
    {
        if (!$data) {
            return $data;
        }

        $alias = key(current($data));
        $options += array(
            'idPath' => "{n}.$alias.id",
            'parentPath' => "{n}.$alias.parent_id",
            'children' => 'children',
            'root' => null
        );

        $return = $idMap = array();
        $ids = self::extract($data, $options['idPath']);

        $idKeys = explode('.', $options['idPath']);
        array_shift($idKeys);

        $parentKeys = explode('.', $options['parentPath']);
        array_shift($parentKeys);

        foreach ($data as $result) {
            $result[$options['children']] = array();

            $id = self::get($result, $idKeys);
            $parentId = self::get($result, $parentKeys);

            if (isset($idMap[$id][$options['children']])) {
                $idMap[$id] = array_merge($result, (array)$idMap[$id]);
            } else {
                $idMap[$id] = array_merge($result, array($options['children'] => array()));
            }
            if (!$parentId || !in_array($parentId, $ids)) {
                $return[] =& $idMap[$id];
            } else {
                $idMap[$parentId][$options['children']][] =& $idMap[$id];
            }
        }

        if (!$return) {
            throw new InvalidArgumentException(
                __d(
                    'cake_dev',
                    'Invalid data array to nest.'
                )
            );
        }

        if ($options['root']) {
            $root = $options['root'];
        } else {
            $root = self::get($return[0], $parentKeys);
        }

        foreach ($return as $i => $result) {
            $id = self::get($result, $idKeys);
            $parentId = self::get($result, $parentKeys);
            if ($id !== $root && $parentId != $root) {
                unset($return[$i]);
            }
        }
        return array_values($return);
    }
public static function nest(array $data, $options = array())
    {
        if (!$data) {
            return $data;
        }

        $alias = key(current($data));
        $options += array(
            'idPath' => "{n}.$alias.id",
            'parentPath' => "{n}.$alias.parent_id",
            'children' => 'children',
            'root' => null
        );

        $return = $idMap = array();
        $ids = self::extract($data, $options['idPath']);

        $idKeys = explode('.', $options['idPath']);
        array_shift($idKeys);

        $parentKeys = explode('.', $options['parentPath']);
        array_shift($parentKeys);

        foreach ($data as $result) {
            $result[$options['children']] = array();

            $id = self::get($result, $idKeys);
            $parentId = self::get($result, $parentKeys);

            if (isset($idMap[$id][$options['children']])) {
                $idMap[$id] = array_merge($result, (array)$idMap[$id]);
            } else {
                $idMap[$id] = array_merge($result, array($options['children'] => array()));
            }
            if (!$parentId || !in_array($parentId, $ids)) {
                $return[] =& $idMap[$id];
            } else {
                $idMap[$parentId][$options['children']][] =& $idMap[$id];
            }
        }

        if (!$return) {
            throw new InvalidArgumentException(
                __d(
                    'cake_dev',
                    'Invalid data array to nest.'
                )
            );
        }

        if ($options['root']) {
            $root = $options['root'];
        } else {
            $root = self::get($return[0], $parentKeys);
        }

        foreach ($return as $i => $result) {
            $id = self::get($result, $idKeys);
            $parentId = self::get($result, $parentKeys);
            if ($id !== $root && $parentId != $root) {
                unset($return[$i]);
            }
        }
        return array_values($return);
    }
public static function nest ( array $ data , $ options = array ( ) ) { if ( ! $ data ) { return $ data ; } $ alias = key ( current ( $ data ) ) ; $ options += array ( 'idPath' => "{n}.$alias.id" , 'parentPath' => "{n}.$alias.parent_id" , 'children' => 'children' , 'root' => null ) ; $ return = $ idMap = array ( ) ; $ ids = self :: extract ( $ data , $ options [ 'idPath' ] ) ; $ idKeys = explode ( '.' , $ options [ 'idPath' ] ) ; array_shift ( $ idKeys ) ; $ parentKeys = explode ( '.' , $ options [ 'parentPath' ] ) ; array_shift ( $ parentKeys ) ; foreach ( $ data as $ result ) { $ result [ $ options [ 'children' ] ] = array ( ) ; $ id = self :: get ( $ result , $ idKeys ) ; $ parentId = self :: get ( $ result , $ parentKeys ) ; if ( isset ( $ idMap [ $ id ] [ $ options [ 'children' ] ] ) ) { $ idMap [ $ id ] = array_merge ( $ result , ( array ) $ idMap [ $ id ] ) ; } else { $ idMap [ $ id ] = array_merge ( $ result , array ( $ options [ 'children' ] => array ( ) ) ) ; } if ( ! $ parentId || ! in_array ( $ parentId , $ ids ) ) { $ return [ ] = & $ idMap [ $ id ] ; } else { $ idMap [ $ parentId ] [ $ options [ 'children' ] ] [ ] = & $ idMap [ $ id ] ; } } if ( ! $ return ) { throw new InvalidArgumentException ( __d ( 'cake_dev' , 'Invalid data array to nest.' ) ) ; } if ( $ options [ 'root' ] ) { $ root = $ options [ 'root' ] ; } else { $ root = self :: get ( $ return [ 0 ] , $ parentKeys ) ; } foreach ( $ return as $ i => $ result ) { $ id = self :: get ( $ result , $ idKeys ) ; $ parentId = self :: get ( $ result , $ parentKeys ) ; if ( $ id !== $ root && $ parentId != $ root ) { unset ( $ return [ $ i ] ) ; } } return array_values ( $ return ) ; }
Takes in a flat array and returns a nested array

### Options:

- `children` The key name to use in the resultset for children.
- `idPath` The path to a key that identifies each entry. Should be
compatible with Hash::extract(). Defaults to `{n}.$alias.id`
- `parentPath` The path to a key that identifies the parent of each entry.
Should be compatible with Hash::extract(). Defaults to `{n}.$alias.parent_id`
- `root` The id of the desired top-most result.

@param  array $data    The data to nest.
@param  array $options Options are:
@return array of results, nested
@see    Hash::extract()
@throws InvalidArgumentException When providing invalid data.
@link   http://book.cakephp.org/2.0/en/core-utility-libraries/hash.html#Hash::nest
Takes in a flat array and returns a nested array