dzona
dzona

Reputation: 3751

Yii CSqlDataProvider() and MSSQL - last page bug

I'm using Yii 1.1.16 and CSqlDataProvider() to display data in CGridView. When go to last page I get last PageSize count records, instead number of records on last page. For example, I have grid with 12 record and PageSize set to 10, which means I have 2 pages, so on page 1, I get records from 1 - 10, but on page 2 (last page) I get records 3 - 12!

This are values I get on each page

//on page 1
$dataProvider->getPagination()->getPageCount(); //2
$dataProvider->getPagination()->currentPage; //0
$dataProvider->getPagination()->offset; //0

//on page 2
$dataProvider->getPagination()->getPageCount(); //2
$dataProvider->getPagination()->currentPage; //1
$dataProvider->getPagination()->offset; //10

As you can see, this is values I should get on pages, and data displayed should be correct,but aren't.

I intentionally wrote Yii version, because this was working before Yii upgrade from 1.1.8

One more thing, I'm using MSSQL (Microsoft SQL) database for providing data

Upvotes: 0

Views: 244

Answers (1)

dzona
dzona

Reputation: 3751

Seems like this is Yii framework issue with MSSQL and here is one of solutions, overriding CSqlDataProvider

class MSSqlDataProvider extends CSqlDataProvider
{

    /**
     * Fetches the data from the persistent data storage.
     * @return array list of data items
     */
    protected function fetchData()
    {
        $sql = $this->sql;
        $db = $this->db === null ? Yii::app()->db : $this->db;
        $db->active = true;

        if (($sort = $this->getSort()) !== false) {
            $order = $sort->getOrderBy();
            if (!empty($order)) {
                if (preg_match('/\s+order\s+by\s+[\w\s,]+$/i', $sql))
                    $sql.=', ' . $order;
                else
                    $sql.=' ORDER BY ' . $order;
            }
        }

        if (($pagination = $this->getPagination()) !== false) {
            $pagination->setItemCount($this->getTotalItemCount());
            $limit = $pagination->getLimit();
            $offset = $pagination->getOffset();

            // update limit to the correct value for the last page 
            if ($offset + $limit > $pagination->getItemCount())
                $limit = $pagination->getItemCount() - $offset;

            $sql = $db->getCommandBuilder()->applyLimit($sql, $limit, $offset);
        }

        $command = $db->createCommand($sql);
        foreach ($this->params as $name => $value)
            $command->bindValue($name, $value);

        return $command->queryAll();
    }

}

Thanks to this post.

Upvotes: 1

Related Questions