Мы продолжаем разработку собственной системы отслеживания ошибок. И сегодня подробно рассмотрим создание страниц нашего приложения.
В предыдущих частях мы определились с типами страниц. Напомню, их всего два: страницы с общим перечнем багов (главная и страницы категорий) и страницы отдельных багов с комментариями.
Т.к. общее количество записей о багах может быть большим, мы будем использовать библиотеку pagination, входящую в состав фреймворка CodeIgniter, для вывода этого списка по частям.
Количество записей на одной странице мы задаем в файле конфигурации (application\config\config.php).
$config['bugs_per_page'] = 5;
Получить значение этого параметра можно так:
$this->config->item('bugs_per_page');
Теперь определимся с названиями методов контроллера и структурой URL.
По-умолчанию, URL в CodeIgniter имеют такой вид:
sitename.domen/index.php/имя_контроллера/имя_метода/параметр1/параметр2/…
Контроллер у нас будет называться bugtracker, а метод, показывающий страницы с багами – page. В результате получим URL с такой структурой:
…/bugtracker/page/номер_записи
В последнем сегменте адреса указываем номер первой записи на текущей странице. Кстати, это не id бага в базе данных, это его индекс в массиве с результатами поиска по БД.
Создаём контроллер (application\controllers\bugtracker.php)
class BugTracker extends Controller {
//настройки отображения списка багов
private $listConf = array(
'commentOpen'=>'<li class="depth-{depth}">'
);
function BugTracker() {
parent::Controller();
$this->load->model('mbug');
$this->load->model('mcategory');
$this->load->model('mcomment');
$this->load->library('Table2Tree');
$this->load->library('session');
$this->load->helper('form');
}
function index() {
$this->page();
}
function page($firstBug = 0) {
...
}
}
Как видите, на данный момент он содержит конструктор, в котором мы загрузили модели и несколько библиотек, а также два метода.
1) index – вызывается CodeIgniter’ом если имя метода явно не указано в URL;
2) page($firstBug = 0) – показывает записи о багах начиная с $firstBug.
Т.к. на главной странице у нас будет отображаться список багов начиная с первого, то из метода index мы просто вызываем page без параметров.
Теперь подробно рассмотрим метод page.
function page($firstBug = 0) {
if (!is_integer((int)$firstBug)) {
$firstBug = 0;
}
//сохраняем адрес этой страницы в сессии
$this->session->set_userdata(array('prev_page'=>current_url()));
$pageData['title'] = 'Bug Tracker';
//настраиваем разбивку на страницы
$this->load->library('pagination');
$pconf['base_url'] = $this->config->item('base_url').'bugtracker/page';
$pconf['total_rows'] = $this->mbug->getBugsCount();
$pconf['per_page'] = $this->config->item('bugs_per_page');
$this->pagination->initialize($pconf);
$pageData['paginationLinks'] = $this->pagination->create_links();
//загружаем общий список ошибок и комментариев к ним
$bugs = $this->mbug->getAllBugs($firstBug, $this->config->item('bugs_per_page'));
if ($bugs !== false) {
$bugsTree = $this->table2tree->getTree($bugs, $firstBug, $this->config->item('bugs_per_page'));
$pageData['bugsList'] = $this->table2tree->getHTMLList($bugsTree, $this->listConf);
}
$pageData['categories'] = $this->mcategory->getAllCategories();
$this->load->view('header', $pageData);
$this->load->view('categories');
//размещаем форму отправки сообщений о багах
$this->load->view('addbugform');
$this->load->view('allbugs');
$this->load->view('footer');
}
Его работу можно разделить на следующие этапы.
1) Проверяем параметр и сохраняем адрес текущей страницы в сессии (зачем это нужно я расскажу немного позже).
2) Настраиваем разбивку на страницы (строки 11-18). Для этого загружаем библиотеку pagination, передаём ей массив с параметрами и создаем ссылки. В качестве параметров мы указываем: общее количество записей (получаем с помощью метода getBugsCount()), количество записей, которые нужно показать на странице (читаем из конфига) и первую часть URL ссылок (к нему последним параметром библиотека будет добавлять номер первой записи на очередной странице).
Т.е. если мы показываем по 5 записей на странице, библиотека создаст такие URL:
.../bugtracker/page/
.../bugtracker/page/5
.../bugtracker/page/10
…
После этого мы загружаем список багов для данной страницы (строка 21). Запрос, который формирует этот список мы рассматривали в прошлый раз.
3) С помощью библиотеки table2tree мы преобразуем таблицу с данными о багах в HTML список (строки 23-28).
4) Загружаем список категорий (строка 30). Он используется для создания навигации по баг трекеру.
5) Показываем страницы (строки 32-37). Для этого загружаем представления и передаем им параметры.
Подробно рассматривать все представления смысла я не вижу. В любом случае оформлением я не занимался, поэтому, скорее всего, их придется немного изменить. Например, добавить CSS классы. Но на принцип работы и передаваемые данные это влиять не будет.
Поэтому сейчас я просто приведу краткое описание всех представлений. Все они находятся в папке (application\views):
header.php – формирует заголовок страницы, загружает JavaScript и CSS файлы;
categories.php – формирует список с перечнем категорий (используется для навигации);
addbugform.php – форма добавления записи о найденном баге;
allbugs.php – показывает список багов и строку со ссылками на другие страницы;
footer.php – «хвостовик» страницы.
Создание страницы выбранной категории.
Приводить код этого метода я не буду, т.к. он практически полностью повторяет метод page. Тем не менее, есть несколько нюансов на которых стоит остановиться.
Во-первых, метод контроллера, создающий страницу отдельной категории, называется category и принимает 2 параметра: название категории и номер первой записи на странице.
Т.е. URL имеет такой вид:
…/bugtracker/category/имя_категоии/номер_записи
Во-вторых, при настройке библиотеки pagination необходимо явно указать в каком сегменте URL находится номер первой записи (по-умолчанию, это значение равно 3).
$pconf['uri_segment'] = 4;
В третьих, список багов получаем с помощью метода getBugsByCategory (модель mbugs). В прошлый раз мы рассматривали SQL запрос, который возвращает список багов для указанной категории.
Остальной код полностью повторяет метод page.
Создание страницы отдельного бага (метод bug).
function bug($id = 1) {
if (!is_integer((int)$id) || (int)$id <= 0) {
redirect('bugtracker/index');
return;
}
//сохраняем адрес этой страницы в сессии
$this->session->set_userdata(array('prev_page'=>current_url()));
//ищем указанный баг
$bug = $this->mbug->getBug($id);
if ($bug !== false) {
$bugTree = $this->table2tree->getTree($bug);
$pageData['bugList'] = $this->table2tree->getHTMLList($bugTree, $this->listConf);
$pageData['bug_id'] = $bugTree[0]['id'];
}
$pageData['categories'] = $this->mcategory->getAllCategories();
$this->load->view('header', $pageData);
$this->load->view('categories');
$this->load->view('onebug');
$this->load->view('addcommentform');
$this->load->view('footer');
}
Этот метод очень похож на предыдущие. Но есть несколько существенных различий.
1) Здесь мы не используем библиотеку pagination. В ней просто нет смысла. На странице отображается запись только об одном баге и все комментарии к нему.
2) Данные бага загружаем с помощью метода getHTMLList (строка 15). Кстати, для создания дерева комментариев мы используем собственную библиотеку table2tree. Её методы getTree и getHTMLList автоматически определяют есть ли в исходных данных комментарии и глубину их вложенности.
3) Вместо формы добавления бага вставляем форму добавления комментария (строка 24).
На этом мы закончим эту часть.
В следующий раз рассмотрим добавление записей и комментариев.
До встречи!


