Thanks for the code.

After further investigation, it appears that the issue is not with Zend_Db_Table_Rowset, but with the SPL SeekableIterator class, and how PHP handles iterators and foreach loops. The foreach loop executes a rewind() before beginning, therefore resetting our pointer to 0. It would seem to make sense for SeekableIterator to be able to move the pointer, then the foreach loops start where the pointer is telling it to. Zend_Db_Table_Rowset could handle this on its own, but it seems that would be the entire point of implementing SeekableIterator as opposed to Iterator. IE:

// in Zend_Db_Table_Rowset_Abstract

protected $_seek = false;

public function seek($position)
{
   // do all the stuff seek does
   $this->_seek = true;
}

public function rewind()
{
   if (!$this->_seek) {
      $this->_pointer = 0;
   }
   $this->_seek = false;
   return $this;
}

That code isn't great, but doing something like this could get around PHP's rewind at the beginning of foreach loops, but it seems kinda hack-ish to me.

Thoughts?

Cameron wrote:
I built something like this as a paginator for when you're on your item view. What I did was build a simple class that implements the SPL Iterator and Countable classes, just like the internal Zend_Paginator, but just uses an array as its internal guts. Then I simply grabbed all the id fields from my table and passed it as an array through to my paginator class' constructor, and then called the setCurrentItem method to correctly position the pointer in array. I have no idea if something like this helps you at all, but it seemed a pretty clean way of solving my particular problem, which was getting a "next" and "previous" button on my record display. Here's the class anyway, if it helps.

class ItemPaginator implements Countable, Iterator
{
    protected $collection;
    protected $count;
    protected $pointer_position;
public function __construct( $collection ) {
      $this->collection = $collection;
      $this->count = sizeof($this->collection);
    }
public function count() {
        return $this->count;
    }
public function key() {
      return $this->pointer_position;
    }

    public function current() {
      return $this->collection[$this->pointer_position];
    }

public function next() { $this->pointer_position++;
    }

    public function rewind() {
      $this->pointer_position = 0;
    }
public function valid() {
      return strlen( $this->collection ) > $this->pointer_position;
} public function getNextItem() {
        if ($this->pointer_position < $this->count) {
            return $this->collection[$this->pointer_position + 1];
        }
        return false;
    }
public function getPrevItem() {
        if ($this->pointer_position > 0 ) {
            return $this->collection[$this->pointer_position - 1];
        }
        return false;
    }
public function getFirstItem() {
        if ($this->pointer_position > 0 ) {
            return $this->collection[0];
        }
        return false;
    }
public function getLastItem() {
        if ($this->pointer_position < $this->count ) {
return $this->collection[$this->count - 1]; // -1 for the array offset
        }
        return false;
    }
public function setCurrentItem($item) {
        $key = array_search($item, $this->collection);
        if (FALSE !== $key) {
            $this->pointer_position = $key;
            return true;
        }
        return false;
    }
}


Sorry if this is really terrible code that I should be implementing completely differently, the SPL is all a bit new to me :)



On Fri, Nov 7, 2008 at 1:17 AM, Jason Austin <[EMAIL PROTECTED] <mailto:[EMAIL PROTECTED]>> wrote:

    I have a need to paginate some simple results, which I need the
    count of the entire rowset, and then rows from a particular
    offset.  I don't really want to execute 2 queries, so I was
    thinking of using the seek() method of my result set to put the
    pointer to the required offset, however when I loop through the
    results it starts over at the beginning of the result set:

    <?php

    $rows = $model->fetchAll($where, $order);

    $rows->seek($page * $resultsPerPage);

    echo $rows->current()->id  // echoes correct "seek()" offset ID

    foreach ($rows as $r) {  // starts over at the beginning of the rowset
      // add to result set
    }

    ?>

    Is this the expected behavior or am I missing something totally
    obvious?  This is with version 1.6.1. <http://1.6.1.>  Should I
    just do 2 queries (a query to get the required rows, then a count
    query without qualifier)?

    Thanks!
    Jason

-- Jason Austin
    Senior Solutions Implementation Engineer
    NC State University - Office of Information Technology
    http://webapps.ncsu.edu
    919.513-4372



--
Jason Austin
Senior Solutions Implementation Engineer
NC State University - Office of Information Technology
http://webapps.ncsu.edu
919.513-4372

Reply via email to