EllisLab text mark
Advanced Search
     
Nested data
Posted: 28 January 2010 08:48 AM   [ Ignore ]
Joined: 2009-10-28
3 posts

Hi!

I’m an MVC newbie but I have a fair bit of experience as a programmer. I would like to hear your opinion on an MVC issue.

Thing is, I have some nested data in my model. I cannot reliably make assumptions about the structure of the data in terms number of levels etc., because that structure is implicit in a database table (row elements that have pointers to parents). Which means I cannot hardcode the structure as ie. foreach(foreach)-loops in a view.

So where do I put the code to present it? I’m reluctant to add HTML-producing code in my model but I also don’t want to add a lot of complex, possibly recursive code to the view or controller.

Another thought is that I send HTML-snippets from the controller to some sort of decoration method in the model. But that means I get some HTML in the controller…

What do you think?

TIA,
Emanuel

 
Posted: 28 January 2010 12:08 PM   [ Ignore ]   [ # 1 ]   [ Rating: 0 ]
Avatar
Joined: 2008-07-20
262 posts

You should try and have all of your HTML served from views, it’s what they are there to do. Removing HTML from your models/controllers into the views should clean up your controllers/models as well so you’re code will be nicer and easier to follow.

To represent your tree like structure, you’ll need to pull all the data from your model as a flat structure and turn it into a tree (an array with nested elements). That way you can properly transverse the data and output it in your views.

If you just search online for transversing trees in php, and turning flat structures into trees there’s plenty of code snippets. I actually had to do this for a work project recently. I created a library with a couple of functions to do this. I don’t have the code with me at the moment but I can give you a rough idea of what it would look like if you’d like.

 Signature 

I heard that big fonts are in this summer? All the cool kids seem to be doing it!  | Mario Visic - Freelance Web Programmer | HumorList - It’s got stripes!

 
Posted: 29 January 2010 09:30 AM   [ Ignore ]   [ # 2 ]   [ Rating: 0 ]
Joined: 2009-10-28
3 posts

Okay, I ended up creating a treeview library. The library simply injects special symbols for nesting start/end when flattening the tree. This removed all markup from my model and made my view trivial (no ugly recursive code):

<?foreach($nested as $row):?>
<?if
(is_array($row)):?>
<li>stuff<?=$row['xyz']?></li>
<?else:?>
<?php 
switch($row){
    
case 'nbegin':
        echo 
'<ul>';
        break;
    case 
'nend':
        echo 
'</ul>';
        break;
}
?>
<?endif?>
<?endforeach?> 

Sometimes the solution is really simple.

 
Posted: 29 January 2010 09:42 AM   [ Ignore ]   [ # 3 ]   [ Rating: 0 ]
Joined: 2009-10-28
3 posts

I’ll post the library too. It’s really quite general. The only assumption is that the data has parent pointers and priorities.

<?php


class treeview
{
    
private $idkey;
    private 
$pkey;
    private 
$ina// implicitly nested array (elems with parent pointers)
    
private $byid;
    private 
$children;
    private 
$tv;
    private 
$tvbyid;

    private function 
_flatten($root$level)
    
{
        
if(!array_key_exists($root$this->children))
        
{
            
return;
        
}
        
        $c 
$this->children[$root];
        if(
count($c) == 0// shouldn't happen, but just to be on the safe side of things
        
{
            
return;
        
}

        $this
->tv[] 'nbegin';

        foreach(
$c as $id)
        
{
            $idx 
$this->byid[$id];
            
$this->tv[]= array( '_id' => $id'_level' => 0'_idx' => $idx ) + $this->ina[$idx];
           
            
$this->_flatten($id$level 1);
        
}
        
        $this
->tv[] 'nend';
    
}

    
private function flatten()
    
{
        $this
->tv = array( );
        
$this->_flatten(00);
        
        foreach(
$this->tv as $idx => $a)
        
{
            $id 
$a['_id'];
            
$this->tvbyid[$id] $idx;
        
}
    }
    
    
function make_treeview($ina$idkey$pkey$prikey)
    
{
        $this
->ina $ina;
        
$this->idkey $idkey;
        
$this->pkey $pkey;
        
$this->prikey $prikey;
        
$this->byid = array( );
        
$this->children = array( );
               
        foreach(
$this->ina as $idx => $row)
        
{
            $id 
$row[$this->idkey];
            
$parent $row[$this->pkey];
            
$priority $row[$this->prikey];
            
            if(!
array_key_exists($parent$this->children))
            
{
                $this
->children[$parent] = array( );
            
}
            
            $this
->byid[$id] $idx;
            
$this->children[$parent][$priority] $id;
        

        
        
# this key sort arranges siblings in order of priority
        
        
foreach($this->children as $parent => $clist)
        
{
            ksort
($this->children[$parent]);
        
}
        
        $this
->flatten();
        
        return 
$this->tv;
    
}
}
?> 
 
Posted: 29 January 2010 10:20 AM   [ Ignore ]   [ # 4 ]   [ Rating: 0 ]
Avatar
Joined: 2008-07-20
262 posts

Good old recursive functions.

 Signature 

I heard that big fonts are in this summer? All the cool kids seem to be doing it!  | Mario Visic - Freelance Web Programmer | HumorList - It’s got stripes!