Search code examples
phpzend-framework2zend-db-selectzend-paginator

Need dynamic column information from Zend Paginator Object


I am building a plugin for grid listing ( for my personal use of course ). Now I integrated ZF2 Paginator as in link http://framework.zend.com/manual/2.1/en/tutorials/tutorial.pagination.html . I am using DB Select for Paginator (Not Array). I need fields name as dynamic one, So i can iterate them, Something like that

<?php $headers = $this->paginator->getFirstRow()->getColumns(); ?>
<tr>
<?php foreach ($headers as $col) : ?>
    <th><?php echo $col; ?></th>
<?php endforeach; ?>
</tr>

<?php foreach ($this->paginator as $row) : ?>
    <tr>
    <?php foreach ($row->getColumns() as $col) : ?>
        <td><?php echo $row->{$col}; ?></td>
    <?php endforeach; ?>
    </tr>
<?php endforeach; ?>

As this is practice project, I really no need to integrate some already existed 3rd party grid solutions. I just want to know if something similar like above is possible using Zend Paginator API ?

UPDATE : Problem finally fixed. Solution is very much match to @netiul's solution with some modifications .

In Plugin Helper :

$resultSet = $paginator->getIterator(); 

$columnNames = array_keys(get_object_vars($resultSet->getArrayObjectPrototype()));

$grid .= '<thead><tr>';
foreach($columnNames as $header)
{
    $grid .= '<th>'.$header.'</th>';
}
$grid .= '</tr></thead>';

$grid .= '<tbody>';
foreach($resultSet as $row)
{
    $grid .= '<tr>';
    foreach($columnNames as $col)
    {
        $grid .= '<td>'.$row->$col.'</td>';
    }
}
$grid .= '</tbody>';

Also one change needed in Model (Alas I need to make this change outside plugin, don't now how to fix except a Model parent class which override by all project models ).

I need to add resultset buffer to fix forward cursor error like This result is a forward only result set, calling rewind() after moving forward is not supported - Zend )

In Model :

public function __construct(Adapter $adapter)
{
    $this->adapter = $adapter;
    $this->resultSetPrototype = new ResultSet();
    $this->resultSetPrototype->buffer();  // New Line added for buffer
    $this->resultSetPrototype->setArrayObjectPrototype(new Leads());
    $this->initialize();
}

Solution

  • So, to recap your question: you want to output the contents of a paginator of which you don't know the columnnames, since they may be dynamic?

    Let's assume we've a valid Paginator with results and unknown column names. These are the steps to correctly output them:

    1. Fetch the column names of the first row and put them in an array.
    2. Generate the header of the table/grid.
    3. Use the array to walk over the rows to match the table header sequence.

    That could look like as following.

    $firstItem = reset($paginator->getIterator());
    $columnNames = array_keys(get_object_vars($firstItem));
    
    // optional do some sorting here like `sort($columNames)`
    
    echo '<thead><tr>';
    foreach ($columnNames as $columnName) {
        echo '<th>' . $columnName . '</th>';
    }
    echo '</tr></thead>';
    
    echo '<tbody>';
    foreach ($paginator as $item) {
        echo '<tr>';
        foreach ($columnNames as $columnName) {
            echo '<td>' . $item->$columnName . '</td>';
        }
        echo '</tr>';
    }
    echo '</tbody>';