web-dev-qa-db-ja.com

モデルgetListQuery()はJPaginationを使用してすべての行をフェッチします

モデルにgetListQuery()メソッドがあり、クエリを返します。ご存知のように、JoomlaはJPaginationを使用するときにクエリの制限とオフセットを自動的に設定します。 JPaginationを使用してgetListQuery()ですべての行をフェッチしたいという問題があります。限り、私は次のようなコードを書きました

protected function getListQuery(){

    // here is created my $query object with query

    // I'm fetching all rows
    $rows = $db->loadObjectList();
    $this->rows = $rows;

    return $query;

}

つまり、クエリは2回実行されます。1つはこのメソッドで、もう1つはJoomlaコアです。ページの読み込みが2倍長くなるため、このソリューションにはあまり満足していません。クエリには約10の結合があります...何百万もの行があるため、それは本当に問題です。正しい解決策はありますか?

7
turson

私は解決策を見つけました(私は思う)。 JModelListメソッドを上書きしました。

class MyComponentModel extends JModelList{

    protected $_items = array();

    public function getItems() {
        // Get a storage key.
        $store = $this->getStoreId();

        // Try to load the data from internal storage.
        if (isset($this->cache[$store])) {
            return $this->cache[$store];
        }
        $query = $this->getQuery();
        $this->query = $query;
        $db = JFactory::getDbo();
        $db->setQuery($query);
        $rows = $db->loadObjectList();
        $this->cache[$store] = $rows;
        $this->_items = $rows;
        return array_slice($rows, $this->getStart(), $this->getState('list.limit'));
    }

    public function getPagination() {
        // Get a storage key.
        $store = $this->getStoreId('getPagination');

        // Try to load the data from internal storage.
        if (isset($this->cache[$store])) {
            return $this->cache[$store];
        }

        // Create the pagination object.
        jimport('joomla.html.pagination');
        $limit = (int) $this->getState('list.limit') - (int) $this->getState('list.links');
        $page = new JPagination($this->getTotal(), $this->getStart(), $limit);

        // Add the object to the internal cache.
        $this->cache[$store] = $page;

        return $this->cache[$store];
    }

    function getTotal() {
        return count($this->_items);
    }

    public function getQuery() {
        // query
        return $query;
    }

}

view.html.php

$this->model = $this->getModel();
$this->items = $this->model->getItems();
$this->pagination = $this->model->getPagination();

ページの読み込みがはるかに速くなります。それは良い解決策ですか?

6
turson

JoomlaはgetItemsを使用してクエリを実行する必要があります。したがって、最善の策は、モデルの状態を変更して、すべての結果が確実に読み込まれるようにすることです。

モデル内では、次のようにsetStateを使用してこれを行うことができます。

$this->setState('list.limit', 0);

モデルがgetItemsを呼び出す前にそれを実行すると、すべてのアイテムが読み込まれます。


これに関するいくつかの警告。

  1. モデルの外でこれを行うこともできるので、たとえば、自分のビューにいた場合。次のことができます。

    $ model = $ this-> getModel(); $ model-> setState( 'list.limit'、0);

  2. 場合によっては、モデルの状態が入力される前にこれを行うのが早すぎる可能性があります。これにより、制限を設定した後、基本的に制限をオーバーライドした後、モデルがユーザーの状態から再構築されます。

これを修正するには、最初にモデルにその状態を強制的に設定できます。

$model = $this->getModel();
$model->getState();
$model->setState('list.limit', 0);

実際のpopulateStateメソッドは保護されているため、モデルの外では直接呼び出すことはできませんが、getStateを呼び出すと、populateStateが呼び出されてから状態の現在の設定。

4
David Fritsch