我从头开始创建了一个Varien_Data_Collection:
$myCollection = new Varien_Data_Collection();
在向其添加一些项目$myCollection->addItem($fooItem);
后,我尝试将其分页为:
$myCollection->setPageSize(3)->setCurPage(1);
但是当我显示集合时,它会显示集合中的所有项目,而不是第一页,第二页面。
$myItems = $myCollection->getItems();
foreach ($myItems as $item) {
echo $item->getData('bar');
}
答案 0 :(得分:1)
(非抽象)基类Varien_Data_Collection
- 虽然它确实有setPageSize
和setCurPage
方法,但这些方法并未反映在迭代器的聚合中:
class Varien_Data_Collection implements IteratorAggregate, Countable
{
...
/**
* Implementation of IteratorAggregate::getIterator()
*/
public function getIterator()
{
$this->load();
return new ArrayIterator($this->_items);
}
...
它将在任何案例中返回包含所有对象的ArrayIteator
。 load
方法在这里没有改变btw:
...
/**
* Load data
*
* @return Varien_Data_Collection
*/
public function loadData($printQuery = false, $logQuery = false)
{
return $this;
}
...
/**
* Load data
*
* @return Varien_Data_Collection
*/
public function load($printQuery = false, $logQuery = false)
{
return $this->loadData($printQuery, $logQuery);
}
...
我认为这可以作为一个错误,因为公共接口让人认为magent集合对象Varien_Data_Collection
提供了分页,而不是。
我没有搜索有关此问题的错误报告。解决方案是使用另一个迭代器进行分页,例如an answer到How to Paginate lines in a foreach loop with PHP中使用PHP LimitIterator
概述:
/**
* Class Varien_Data_Collection_Pagination
*
* Aggregates missing Pagination on Collection on getting the Iterator
*
* @author hakre <http://hakre.wordpress.com/>
*/
class Varien_Data_Collection_Pagination implements IteratorAggregate
{
/**
* @var Varien_Data_Collection
*/
private $collection;
public function __construct(Varien_Data_Collection $collection)
{
$this->collection = $collection;
}
public function getIterator()
{
$collection = $this->collection;
if (FALSE === $size = $collection->getPageSize()) {
return $collection;
}
$page = $collection->getCurPage();
if ($page < 1) {
return $collection;
}
$offset = $size * $page - $size;
return new LimitIterator(new IteratorIterator($collection), $offset, $size);
}
}
用法示例:
$collection = new Varien_Data_Collection();
$collectionIterator = new Varien_Data_Collection_Pagination($collection);
# [...] fill collection
# set pagination:
$collection->setPageSize(3);
$collection->setCurPage(1);
echo iterator_count($collectionIterator); # 3 (int)
请记住,这主要是一个例子。恕我直言,这应该在Magento代码库的上游修复,所以你可能值得在Magento Bug-Tracker进行一些搜索工作。
答案 1 :(得分:0)
如前文所述,Varien_Data_collection不支持分页。一种解决方案是扩展此类并覆盖其loadData()方法。这是stdating stdClass对象数组的实际示例。可以与任何数据数组一起使用
类YourNamespace_YourModule_Model_History_Collection扩展了Varien_Data_Collection {
//array of stdClass objects. Can be array of any objects/subarrays
protected $_history = array();
public function loadData($printQuery = false, $logQuery = false){
if ($this->isLoaded()) {
return $this;
}
$this->_totalRecords = count($this->_history);
$this->_setIsLoaded();
// paginate and add items
$from = ($this->getCurPage() - 1) * $this->getPageSize();
$to = $from + $this->getPageSize() ;
$isPaginated = $this->getPageSize() > 0;
$cnt = 0;
$sub_history = array_slice($this->_history, $from, $to-$from);
foreach ( $sub_history as $entry) {
$cnt++;
$item = new $this->_itemObjectClass();
//build here your Varien Object
$item->setDate($entry->Date);
//.......
$this->addItem($item);
if (!$item->hasId()) {
$item->setId($cnt);
}
}
return $this;
}
public function setRecords($records){
if(is_array($records)){
$this->_history = $records;
}
return;
}
}
//你的块类
类YourNamespace_YourModule_Block_History扩展Mage_Core_Block_Template {
public function __construct(){
$collection_prepared = new YourNamespace_YourModule_Model_History_Collection();
//get your data here
//$records is array of stdClass objects
$collection_prepared->setRecords($records);
$this->setCollection($collection_prepared);
}
protected function _prepareLayout(){
parent::_prepareLayout();
$pager = $this->getLayout()->createBlock('page/html_pager', 'history.pager');
$pager->setAvailableLimit(array(20=>20,40=>40,80=>80,'all'=>'all'));
$pager->setCollection($this->getCollection());
$this->setChild('pager', $pager);
$this->getCollection()->load();
return $this;
}
public function getPagerHtml()
{
return $this->getChildHtml('pager');
}
}
希望这有帮助!
答案 2 :(得分:0)
class Pageable_Varien_Data_Collection extends Varien_Data_Collection
{
/**
* Load data
*
* @param bool $printQuery
* @param bool $logQuery
*
* @return Pageable_Varien_Data_Collection
*/
public function load($printQuery = false, $logQuery = false)
{
if ($this->isLoaded()) {
return $this;
}
$this->_renderLimit();
$this->_setIsLoaded();
return $this;
}
/**
* @return Pageable_Varien_Data_Collection
*/
protected function _renderLimit()
{
if ($this->_pageSize) {
$currentPage = $this->getCurPage();
$pageSize = $this->_pageSize;
$firstItem = (($currentPage - 1) * $pageSize + 1);
$lastItem = $firstItem + $pageSize;
$iterator = 1;
foreach ($this->getItems() as $key => $item) {
$pos = $iterator;
$iterator++;
if ($pos >= $firstItem && $pos <= $lastItem) {
continue;
}
$this->removeItemByKey($key);
}
}
return $this;
}
/**
* Retrieve collection all items count
*
* @return int
*/
public function getSize()
{
if (is_null($this->_totalRecords)) {
$this->_totalRecords = count($this->getItems());
}
return intval($this->_totalRecords);
}
/**
* Retrieve collection items
*
* @return array
*/
public function getItems()
{
return $this->_items;
}
}