Изменить стиль страницы

Мы подключаем файл myquestions.html.phpс помощью require_once(JApplicationHelper::getPath('html')) и папку tableбэкенда с помощью JTable::addIncludePath(). Обратите внимание, что мы обращаемся к классам таблиц бэкенда, хотя пишем фронтенд компонента.

Переключатель switch обрабатывает пока только значение задачи по умолчанию, вызывая функцию для получения списка категорий.

Теперь добавим класс HTML_questions для фронтенда. Создайте файл /components/com_myquestions/myquestions.html.php:

<?php class HTML_questions { function showCategories($rows, $option) { ?> <p><a href='index.php?option=<?=$option?>&task=showlist'><?= JText::_('COM_MYQUESTIONS_ALL_QUESTIONS')?></a></p> <table> <?php foreach($rows as $row) { $link = 'index.php?option='.$option.'&id_cat='.$row->id.'&task=showlist'; echo '<tr><td><p><a href="' . $link . '">'.$row->name .'</a></td><td>'.$row->desc.'</td></tr>'; } ?> </table> <?php } } ?>

Класс HTML_questions будет содержать все функции вывода во фронтенде. Функция showCategories() принимает в качестве параметров массив записей таблицы базы данных и название текущего компонента. В цикле осуществляется обход этого массива и каждая запись выводится на экран.

Создайте файл /language/ru-RU/ru-RU.com_myquestions.iniи скопируйте в него строку:

COM_MYQUESTIONS_ALL_QUESTIONS="Все вопросы"

Теперь на странице компонента myquestions во фронтенде по умолчанию отображается список категорий (рис. 4.9).

Разрботка расширений для CMS Joomla _37.jpg

(есть увеличенное изображение)

Рис. 4.9.  Вывод списка категорий во фронтенде

Просмотр списка вопросов

Измените код конструкции switch в файле myquestions.php, добавив обработку задачи showlist:

case 'showlist': showQuestions($option); break;

Добавьте в этот же файл функцию showQuestions():

function showQuestions($option) { $db =& JFactory::getDbo(); $query = "SELECT q.id,q.name,q.date,q.question,q.city,q.email,q.answer,q.id_cat,c.name AS cname ". "FROM #__myquestions q, #__myquestions_categories c ". "WHERE q.id_cat=c.id AND q.answer <> '' AND (q.published = 1 OR (q.expiration_date <> '0000-00-00 00:00:00' AND q.expiration_date > NOW()))"; $id_cat = JRequest::getVar('id_cat', '0'); if ($id_cat != 0) $query .= " AND q.id_cat = $id_cat"; $db->setQuery($query); $rows = $db->loadObjectlist(); if ($db->getErrorNum()) { echo $db->stderr(); return false; } if ($id_cat != 0) { $query = "SELECT name FROM #__myquestions_categories WHERE id=$id_cat"; $db->setQuery($query); if ($db->getErrorNum()) { echo $db->stderr(); return false; } $name_cat = $db->loadResult(); } else $name_cat = ''; HTML_questions::showQuestions($rows, $option, $name_cat); }

Длинный SQL-запрос требует пояснения. Как вы помните, при описании функциональности нашего компонента упоминалось, что отображаться на сайте будут вопросы, удовлетворяющие следующим условиям:

есть ответ;

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

Данный запрос выбирает вопросы, которые соответствуют этим условиям.

Проверяется значение переменной $id_cat (id категории), и если категория задана, то из базы выбираются только вопросы, отнесенные к этой категории. Затем извлекается название категории для отображения над списком вопросов. Если же категория не задана, то выбираются вопросы из всех категорий.

Добавьте в класс HTML_questions в файле myquestions.html.phpследующую функцию:

function showQuestions($rows, $option, $name_cat) { if ($name_cat !== '') echo "<h1>$name_cat</h1>"; foreach($rows as $row) { $link = 'index.php?option='.$option.'&id='.$row->id.'&task=showquestion'; $link_cat = 'index.php?option='.$option.'&id_cat='.$row->id_cat.'&task=showlist'; ?> <table width="100%"> <tr> <td><i><?=$row->name?></i></td> <td><i><u><?=$row->email?></u></i></td> <td><i><?=JHTML::_('date', $row->date, JText::_('DATE_FORMAT_LC3'))?></i></td> <td><i><?=$row->city?></i></td> </tr> <tr> <td colspan="4"><a href="<?=$link_cat?>"><?=$row->cname?></a></td> </tr> <tr> <td colspan="4"><b><?=$row->question?></b></td> </tr> <tr> <td colspan="4"><?=$row->answer?></td> </tr> <tr> <td colspan="4"><a style="text-decoration: none;" title="<?=JText::_('COM_MYQUESTIONS_READMORE')?>" alt="<?=JText::_ ('COM_MYQUESTIONS_READMORE')?>" href="<?=$link?>">---></a></td> </tr> </table> <br/> <? } }

Данная функция выводит название категории, если оно задано, и затем проходит в цикле по всем записям, переданным ей. Для каждой записи выводится таблица с теми ее полями, которые были извлечены ранее.

Добавьте в файл language/ru-RU/ru-RU.com_myquestions.iniстроку:

COM_MYQUESTIONS_READMORE="Подробнее"

Для проверки работоспособности нового кода нажмите на ссылку " Все вопросы" во фронтенде нашего компонента. Результат должен быть приблизительно таким, как на рис. 4.10.

Разрботка расширений для CMS Joomla _38.jpg

(есть увеличенное изображение)

Рис. 4.10.  Список вопросов во фронтенде

Вывод одного вопроса

Иногда может понадобиться вывести какой-либо один вопрос. Например, если пользователь захочет поделиться ссылкой на свой вопрос с кем-то другим.

Измените код конструкции switch в файле myquestions.php, добавив обработку задачи showquestion:

case 'showquestion': showQuestion($option); break;

Добавьте в этот же файл функцию showQuestion():

function showQuestion($option) { $id = JRequest::getVar('id', 0) ; $row = &JTable::getInstance ('question', 'Table'); $row->load($id); if ($row->answer == '' || ($row->published == 0 && ($row->expiration_date == '0000-00-00 00:00:00' || strtotime($row->expiration_date) <= time()))) JError::raiseError(404, JText::_(' COM_MYQUESTIONS_ERROR404')); $row_cat =& JTable::getInstance('Category','Table'); $row_cat->load($row->id_cat); HTML_questions::showQuestion($row, $option, $row_cat); }

В данном коде мы получаем id из запроса к серверу с помощью функции getVar(). Если значение id отсутствует или неприемлемо, будет использовано значение по умолчанию, переданное во втором параметре (ноль). Затем мы получаем экземпляр класса таблицы из бэкенда и загружаем запись таблицы базы данных, соответствующую идентификатору id.

Далее происходит проверка того, можно ли отображать в открытом доступе данный вопрос. Исходя из условий отображения вопроса на сайте, нетрудно заметить, что не должны отображаться на сайте вопросы, удовлетворяющие хотя бы одному из условий:

нет ответа;

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

Если вопрос не должен отображаться, то используется функция raiseError() класса JError для вывода сообщения " 404 - Вопрос не найден". Такое же сообщение появится при попытке обращения к несуществующей записи.

Добавьте в файл language/ru-RU/ru-RU.com_myquestions.iniстроку: