155 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			155 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| /**
 | |
|  * CDataProviderIterator class file.
 | |
|  *
 | |
|  * @author Charles Pick <charles.pick@gmail.com>
 | |
|  * @link http://www.yiiframework.com/
 | |
|  * @copyright 2008-2013 Yii Software LLC
 | |
|  * @license http://www.yiiframework.com/license/
 | |
|  */
 | |
| 
 | |
| /**
 | |
|  * CDataProviderIterator allows iteration over large data sets without holding the entire set in memory.
 | |
|  *
 | |
|  * CDataProviderIterator iterates over the results of a data provider, starting at the first page
 | |
|  * of results and ending at the last page. It is usually only suited for use with {@link CActiveDataProvider}.
 | |
|  *
 | |
|  * For example, the following code will iterate over all registered users (active record class User) without
 | |
|  * running out of memory, even if there are millions of users in the database.
 | |
|  * <pre>
 | |
|  * $dataProvider = new CActiveDataProvider("User");
 | |
|  * $iterator = new CDataProviderIterator($dataProvider);
 | |
|  * foreach($iterator as $user) {
 | |
|  *	 echo $user->name."\n";
 | |
|  * }
 | |
|  * </pre>
 | |
|  *
 | |
|  * @property CDataProvider $dataProvider the data provider to iterate over
 | |
|  * @property integer $totalItemCount the total number of items in the iterator
 | |
|  *
 | |
|  * @author Charles Pick <charles.pick@gmail.com>
 | |
|  * @author Carsten Brandt <mail@cebe.cc>
 | |
|  * @package system.web
 | |
|  * @since 1.1.13
 | |
|  */
 | |
| class CDataProviderIterator extends CComponent implements Iterator, Countable
 | |
| {
 | |
| 	private $_dataProvider;
 | |
| 	private $_currentIndex=-1;
 | |
| 	private $_currentPage=0;
 | |
| 	private $_totalItemCount=-1;
 | |
| 	private $_items;
 | |
| 
 | |
| 	/**
 | |
| 	 * Constructor.
 | |
| 	 * @param CDataProvider $dataProvider the data provider to iterate over
 | |
| 	 * @param integer $pageSize pageSize to use for iteration. This is the number of objects loaded into memory at the same time.
 | |
| 	 */
 | |
| 	public function __construct(CDataProvider $dataProvider, $pageSize=null)
 | |
| 	{
 | |
| 		$this->_dataProvider=$dataProvider;
 | |
| 		$this->_totalItemCount=$dataProvider->getTotalItemCount();
 | |
| 
 | |
| 		if(($pagination=$this->_dataProvider->getPagination())===false)
 | |
| 			$this->_dataProvider->setPagination($pagination=new CPagination());
 | |
| 
 | |
| 		if($pageSize!==null)
 | |
| 			$pagination->setPageSize($pageSize);
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Returns the data provider to iterate over
 | |
| 	 * @return CDataProvider the data provider to iterate over
 | |
| 	 */
 | |
| 	public function getDataProvider()
 | |
| 	{
 | |
| 		return $this->_dataProvider;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Gets the total number of items to iterate over
 | |
| 	 * @return integer the total number of items to iterate over
 | |
| 	 */
 | |
| 	public function getTotalItemCount()
 | |
| 	{
 | |
| 		return $this->_totalItemCount;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Loads a page of items
 | |
| 	 * @return array the items from the next page of results
 | |
| 	 */
 | |
| 	protected function loadPage()
 | |
| 	{
 | |
| 		$this->_dataProvider->getPagination()->setCurrentPage($this->_currentPage);
 | |
| 		return $this->_items=$this->dataProvider->getData(true);
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Gets the current item in the list.
 | |
| 	 * This method is required by the Iterator interface.
 | |
| 	 * @return mixed the current item in the list
 | |
| 	 */
 | |
| 	public function current()
 | |
| 	{
 | |
| 		return $this->_items[$this->_currentIndex];
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Gets the key of the current item.
 | |
| 	 * This method is required by the Iterator interface.
 | |
| 	 * @return integer the key of the current item
 | |
| 	 */
 | |
| 	public function key()
 | |
| 	{
 | |
| 		$pageSize=$this->_dataProvider->getPagination()->getPageSize();
 | |
| 		return $this->_currentPage*$pageSize+$this->_currentIndex;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Moves the pointer to the next item in the list.
 | |
| 	 * This method is required by the Iterator interface.
 | |
| 	 */
 | |
| 	public function next()
 | |
| 	{
 | |
| 		$pageSize=$this->_dataProvider->getPagination()->getPageSize();
 | |
| 		$this->_currentIndex++;
 | |
| 		if($this->_currentIndex >= $pageSize)
 | |
| 		{
 | |
| 			$this->_currentPage++;
 | |
| 			$this->_currentIndex=0;
 | |
| 			$this->loadPage();
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Rewinds the iterator to the start of the list.
 | |
| 	 * This method is required by the Iterator interface.
 | |
| 	 */
 | |
| 	public function rewind()
 | |
| 	{
 | |
| 		$this->_currentIndex=0;
 | |
| 		$this->_currentPage=0;
 | |
| 		$this->loadPage();
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Checks if the current position is valid or not.
 | |
| 	 * This method is required by the Iterator interface.
 | |
| 	 * @return boolean true if this index is valid
 | |
| 	 */
 | |
| 	public function valid()
 | |
| 	{
 | |
| 		return $this->key() < $this->_totalItemCount;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Gets the total number of items in the dataProvider.
 | |
| 	 * This method is required by the Countable interface.
 | |
| 	 * @return integer the total number of items
 | |
| 	 */
 | |
| 	public function count()
 | |
| 	{
 | |
| 		return $this->_totalItemCount;
 | |
| 	}
 | |
| } |