Для постраничной навигации (pagination) в Kohana 3.2 использую модуль:

https://github.com/kloopko/kohana-pagination

Использовать этот модуль достаточно просто:
1. Распаковываем архив в папку с модулями /modules/pagination/
2. Подключаем модуль в bootstrap.php

Kohana::modules(array(
	// 'auth'       => MODPATH.'auth',         // Basic authentication
	// 'cache'      => MODPATH.'cache',      // Caching with multiple backends
	// 'codebench'  => MODPATH.'codebench',  // Benchmarking tool
	 'database'   => MODPATH.'database',     // Database access
	// 'image'      => MODPATH.'image',      // Image manipulation
	 'orm'        => MODPATH.'orm',          // Object Relationship Mapping
	// 'unittest'   => MODPATH.'unittest',   // Unit testing
	// 'userguide'  => MODPATH.'userguide',  // User guide and API documentation
	 'pagination'  => MODPATH.'pagination',  // Pagination
)

3. Тут же в bootstrap.php создаем роут для постраничеой навигации:

Route::set('catalog', 'catalog(/<category>(/<page>))')
	->defaults(array(
                'directory'  => 'index',
                'action' => 'index',
		'controller' => 'catalog',
	));

4. Из папки modules/pagination/config/ в application/config копируем файл
настроек pagination.php. Мой вариант конфига:

'default' => array(

'current_page' => array('source' => 'route', 'key' => 'page'),
// откуда брать параметры из строки или роута и ключ параметров
// source: "query_string" or "route"
'total_items' => 0, //Всего элементов
'items_per_page' => 10, //элементов на страницу
'view' => 'pagination/basic', //Шаблон
'auto_hide' => TRUE, // Скрывать вывод пагинации, если он не нужен
'first_page_in_url' => FALSE, // подставлять единицу в url к первой странице
)

4. В контроллере пишем примерно такой код:

// получаем общее количество (в моем случае) товаров
$count = ORM::factory('product')->count_all();

// передаем значение количества товаров в модуль pagination и формируем ссылки
$pagination = Pagination::factory(array('total_items' => $count));

//получаем товары с указанной позиции ($pagination->offset)
//и указанное количество на страницу ($pagination->items_per_page)
$products = ORM::factory('product')
->limit($pagination->items_per_page)
->offset($pagination->offset)
->find_all();

//выводим данные в вид
$this->template->main = View::factory('index/v_products',
array('products' => $products, 'pagination' => $pagination ));

В итоге получаем например список из $pagination->items_per_page товаров, а под ним ссылки ввиде:
Страницы: << Пред. 1 2 3 След. >>

P.S. при использовании данного модуля было замечено, что не при всех роутах он работает корректно.
Например, есть роут:

Route::set('admin', 'admin(/<controller>(/<action>(/<id>)))')
    ->defaults(array(
                'directory'  => 'admin',
                'controller' => 'main',
        'action'     => 'index',
    ));

и контроллер order с экшеном index:

       $allorders = ORM::factory('order')->order_by('date','DESC');

       $count = $allorders->count_all();
       $pagination = Pagination::factory(array('total_items' => $count));

Так вот, в нем, модуль нормальных ссылок не дает.
В модуле используется следующий механизм формирования ссылок:

URL::site($this->_route->uri(array_merge($this->_route_params,
array($this->config['current_page']['key'] => $page))).$this->query());

где:
$this->_route = $request->route();
$this->_route_params = $request->param();
$this->config['current_page']['key'] = ‘id’;//параметр из роута
На текущий момент поборол это написанием дополнительного роута:

Route::set('adminorders', 'admin/orders(/<id>)')
	->defaults(array(
                'directory'  => 'admin',
                'controller' => 'orders',
		'action'     => 'index',
	));

В будущем надеюсь побороть эту проблему.

Нашел решение проблемы с некоректной работой модуля пагинации:

$pagination = Pagination::factory(array(
    'total_items' => $count,
    'items_per_page' => 50,
  ))
  ->route_params(array(
  'controller' => Request::current()->controller(),
  'action' => Request::current()->action(),
));

т.е. передаем дополнительные параметры о текущем контроллере и экшене в модуль пагинации:

->route_params(array(
  'controller' => Request::current()->controller(),
  'action' => Request::current()->action(),
));

 

 

17 thoughts on “Pagination в Kohana 3.2

  1. При использовании в конфигурации query_string бывает не корректные урлы в пагинаторе.
    Спасает добавление строки после ::factory()
    $pagination->route_params(array('controller' => $this->request->controller(), 'action' => $this->request->action()));

    Reply
  2. у меня ваш вареант не сработал и выдал ошибку (kohana 3.2)
    “Call to undefined method Pagination::route_params()”

    Reply
    • Если используете модуль пагинации указанный в начале статьи, то все должно работать (проверено не только мной, смотри каммент выше).
      А метод в этом модуле такой точно есть, вот доказательство – https://github.com/kloopko/kohana-pagination/blob/3.2/develop/classes/kohana/pagination.php#L323

      Пробуйте копать дальше, ну или выложите код на pastebin.com и запостите ссылку

      Reply
      • спасибо, правда стало работать после того как заменил файл kohana/pagination.php в модуле

        Reply
  3. Код прекрасно работает, но сталкивались Вы с такой проблемой в адр.строке page2
    все в порядке но стоит ввести page999 ошибок конечно нет и сразу переходит к концу но ведь это ошибка как ее поймать ни как не получается помогите

    Reply
    • вы ведь в контроллере модулю пагинации отдаете количество записей и сколько записей выводить на странице, например:

      $count = ORM::factory('page')->count_all();
      $rows_on_page = 30;
      $pagination = Pagination::factory(array('total_items' => $count,
       'items_per_page' => $rows_on_page));
      

      теперь либо сами считаете сколько у вас страниц:

      $max_page_num = $count/$rows_on_page;
      

      либо спрашиваете у модуля:

      $max_page_num = $pagination->total_pages;
      

      и проверяете соответствут ли полученное количество страниц из параметра переданного в url с вашим максимальным и по итогам, например бросаете на 404 страницу, если у вас страниц меньше, чем запросили.

      Reply
      • Да , спасибо помогло. я сделал так :
        $page = $this->request->param(‘page’);
        if($page > $pagination->total_pages){ throw new HTTP_Exception_404(‘Страница “:page” не найдена’, array(‘:page’ => $page));
        exit();}

        Reply
  4. Привет! Сделать сделал, но выводятся все записи и не появилась навигация снизу.
    Мне непонятный момент
    //получаем товары с указанной позиции ($pagination->offset)
    //и указанное количество на страницу ($pagination->items_per_page)
    $products = ORM::factory(‘product’)
    ->limit($pagination->items_per_page)
    ->offset($pagination->offset)
    ->find_all();

    Могли бы его более подробно описать?
    Заранее спасибо

    Reply
  5. Привет, Вадим! Борюсь с проблемой с работой роутинга с пагинацией в Ko3.3
    Так-то в инете написано, что в версиях 3.2 и 3.3 в этом вопросе разницы нет. Использовал роут как у вас в пункте 3. Не работает. При $view -> log = $pagination ->render(); пишет Kohana_Exception [ 0 ]: Required route parameter not passed: name
    С этой проблемой я и борюсь, перебирая разные варианты роутов.
    Адреса выглядят примерно так localhost/kohana/category/Dokumenti
    и со страницами localhost/kohana/category/Dokumenti/2
    Роут у меня такой: http://ideone.com/33ciBn
    Пагинация делается так: http://ideone.com/i8e2h6
    И так же ошибка Kohana_Exception [ 0 ]: Required route parameter not passed: name
    Как только я меняю ‘source’ на ‘query_string’ то ошибки нет, всё работает, но ссылки формирует не так: http://ideone.com/2yhB84

    Подскажите, намекните, пожалуйста,в чем проблема. Заранее спасибо за помощь!

    Reply
    • В статье есть момент: ‘передаем дополнительные параметры о текущем контроллере и экшене в модуль пагинации’ вы пробовали его? Должно помочь.

      Reply
      • Пробовал так. Пишет что нет такого метода у объекта: Call to undefined method Pagination::route_params(). Я использовал не тот модуль пагинации, как в вашей статье. Но похожий. Скорей всего какой-то форк. В моём случае проблема в роутинге, вроде как не проходит параметр name

        Reply
      • Подставил модуль от kloopko с дополнительными парамерами. Такая же ошибка с name

        Reply
  6. Не помогает. Также Required route parameter not passed: name
    У меня $provided_optional = FALSE;
    В общем я переключил пагинацию в query_string и плюнул. Пусть работает и так.
    Потом попробую версию коханы 3.2 и ваш рецепт пагинации. Спасибо большое, что отозвались на просьбу.

    Reply

Leave a reply

required

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>