
Начало на предыдущей странице
Теперь рассмотрим метод _nestedComments
.
function _nestedComments($comments, $parentId, $depth) { $commentsRes = array(); $i = 0; foreach ($comments as $val) { if ($val['parent_id'] == $parentId) { $commentsRes[$i] = $val; $commentsRes[$i]['depth'] = $depth; $commentsRes[$i]['comments'] = $this->_nestedComments($comments, $val['id'], $depth + 1); $i++; } } return $commentsRes; }
Он значительно меньше предыдущего, но принцип его работы сложнее. Прежде всего, обратите внимание на входные параметры:
comments
– массив с комментариями отдельного бага;
parentId
– id
родительского комментария;
depth
– глубина рекурсии.
Думаю, вы уже догадались, что метод рекурсивный, т.е. вызывает сам себя. Причем первый параметр остаётся неизменным, а второй и третий изменяются.
При первом вызове parentId = NULL
(соответствует комментарию верхнего уровня). Мы в цикле перебираем все комментарии и ищем те, у которых элемент parent_id
равен текущему значению parentId
.
Если такой комментарий найден, мы сохраняем его в массив с результатами и пробуем найти его потомков.
Для этого вызываем этот же метод (_nestedComments
), но уже во втором параметре указываем id
текущего комментария.
В результате мы получим дерево комментариев. Глубина рекурсии будет совпадать с уровнем вложенности комментариев.
Переходим к формированию HTML списка.
Рассмотрим метод getHTMLList
.
function getHTMLList($tree, $config = null) { if (!empty($config)) { foreach ($config as $key => $value) { $this->config[$key] = $value; } } $this->CI->load->library('parser'); $html = $this->config['listOpen']."\n"; foreach ($tree as $node) { $html .= $this->config['bugOpen'].$this->CI->parser->parse('bug_tpl', $node, TRUE)."\n"; if (!empty($node['comments'])) { $html .= $this->_convert2HTMLList($node['comments'], 0)."\n"; } $html .= $this->config['bugClose']; } return $html.$this->config['listClose']; }
Его первый параметр – массив с багами и комментариями, который мы получили до этого.
Второй – массив с настройками отображения списка. Он позволяет легко изменять HTML разметку, которую формирует этот метод.
По-умолчанию, поля этого массива имеют следующие значения
private $config = array( 'listOpen' => '<ul>' ,'listClose' => '</ul>' ,'bugOpen' => '<li>' ,'bugClose' => '</li>' ,'commentOpen' => '<li>' ,'commentClose' => '</li>' );
Т.е. будет сформирован ненумерованный список. Изменив значения listOpen
и listClose
на <ol>
и </ol>
мы получим нумерованный список.
Кроме того, в результирующий список данные о багах должны быть вставлены с соответствующей разметкой. Поэтому, чтобы не превращать код метода в мешанину php и html, мы используем встроенный в CodeIgniter шаблонизатор.
Сами шаблоны мы рассмотрим чуть ниже, а сейчас достаточно знать, что с помощью
$this->CI->parser->parse(...)
можно получить соответствующую html разметку.
Теперь взгляните на цикл (строки 9-15). В нём мы перебираем все элементы массива и для каждого вызываем метод _convert2HTMLList
.
function _convert2HTMLList($bugComments, $depth) { $list = ''; $list .= $this->config['listOpen']."\n"; foreach ($bugComments as $comment) { $openTag = str_replace('{depth}', $depth, $this->config['commentOpen']); $list .= $openTag.$this->CI->parser->parse('comment_tpl', $comment, TRUE)."\n"; if (!empty($comment['comments'])) { $list .= $this->_convert2HTMLList($comment['comments'], $depth + 1); } $list .= $this->config['commentClose']."\n"; } $list .= $this->config['listClose']; return $list; }
Думаю, вы заметили, что этот метод тоже рекурсивный. Мы перебираем все элементы массива комментариев и с помощью шаблонизатора формируем HTML разметку.
Если текущий элемент массива имеет вложенный массив с именем comments
(т.е. есть дочерние комментарии), то мы вызываем этот же метод, но в качестве первого параметра передаем ему вложенный массив.
Второй параметр метода содержит значение глубины рекурсии.
Посмотрите на HTML разметку в начале этой статьи. Каждый вызов метода _convert2HTMLList
формирует свой тег <ul>
для комментариев. Так для первого бага этот метод будет вызван 2 раза. Первый раз из метода getHTMLList
при создании списка с комментариями нулевого уровня (комментарий 1, комментрарий 2), а второй раз – рекурсивно при создании списка с ответами на комментарий 2.
В результате мы получим необходимую разметку со вложенными HTML списками.
Теперь посмотрите на шаблоны для багов и комментариев. Они должны быть размещены в папке application\views
.
bug_tpl.php
<div class="bug" id="bug-{id}"> <p class="bugTitle">Название: <?php echo anchor('bugtracker/bug/'.'{id}', '{title}'); ?></p> <p class="bugInfo"> <span class="bugAuthor">Автор: {uname}.</span> <span class="bugCategory">Категория: <?php echo anchor('bugtracker/category/'.'{link}', '{category}'); ?>.</span> <span class="bugDate">Добавлен: {bug_date}.</span> </p> <p class="bugDescription">Описание: {description}</p> </div>
comment_tpl.php
<div class="comment depth-{depth}" id="comment-{id}"> <p class="commentInfo"> <span class="commentAuthor">Автор: {uname}.</span> <span class="commentDate">Дата: {comment_date}.</span> <span class="commentDescription">Ответ: {description}</span> </p> </div>
Обратите внимание на параметры в фигурных скобках. Их имена совпадают с ключами полей в массиве с деревом багов и комментариев. При формировании страницы шаблонизатор CodeIgniter заменит их соответствующими значениями.
На этом я закончу эту часть. В следующий раз мы рассмотрим создание записи о новом баге.
До встречи!
P.S. Как всегда я буду рад услышать любые замечания и комментарии (кроме спамерских 😉 ).
Страница: 1 2