Bug Tracker: ответы на комментарии (часть десятая)

Владимир | | CodeIgniter, HTML, JavaScript, MySQL, PHP, Web разработка.

bug_tracker_logo_part10

В предыдущих частях (1, 2, 3, 4, 5, 6, 7, 8, 9) мы создали практически работоспособную систему отслеживания ошибок.

«Практически» в данном случае означает, что на данный момент у пользователя отсутствует возможность отвечать на комментарии. Т.е. можно оставить только комментарий 1-ого уровня (комментарий к багу).

Сегодня мы исправим этот недостаток.

Напомню, что на стороне сервера поддержка вложенных комментариев уже реализована. В базе данных (таблица comments) есть поле parent_id в котором хранится id родительского комментария.

Кроме того, метод addComment (модели mcomments) принимает массив с данными комментария, одним из полей которого является parent_id.

И, наконец, метод addcomment контроллера читает этот параметр из массива $_POST и передает его модели.

Таким образом, нам остается обеспечить возможность посетителю указывать на какой комментарий он хочет ответить.

В принципе, реализовать эту возможность можно без JavaScript. Но при этом пользоваться ей будет очень не удобно. Нам придется сформировать выпадающий список с перечнем id всех комментариев к данному багу, а посетитель вручную будет выбирать на какой он хочет ответить. Не думаю, что кому-то понравиться работать с такой формой.

Ситуация совершенно меняется если использовать JavaScript. Под каждым комментарием мы создадим ссылку «Ответить». При клике по ней форма будет перемещаться под выбранный комментарий. Id этого комментария мы сохраним в скрытом поле формы.

Таким образом, детали механизма работы со вложенными комментариями будут совершенно незаметны пользователю. Кстати, комментарии в этом блоге работают именно таким образом.

Переходим к реализации.

Прежде всего, рассмотрим разметку формы.

<form id="fAddComment" method="post" action="http://www.bugtracker.l/bugtracker/addcomment">
	...
	<div>
		<input type="hidden" value="" id="parent_id" name="parent_id"/>
	</div>
	<p>
		<input type="submit" value="Отправить" class="addcomment" id="addcomment" name="addcomment"/>
	</p>
</form>

Чтобы сделать её немного понятнее я опустил поля, которые не имеют отношения ко вложенным комментариями. В данном случае интерес представляет только одно поле — parent_id. В нём хранится id комментария, на который отвечает посетитель. Пустое значение в этом поле соответствует комментарию к багу (первый уровень).

Теперь подключим два JavaScript файла. Первый – библиотека jQuery, второй – файл с нашими функциями.

<script type="text/javascript" src="<?php echo base_url(); ?>js/jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="<?php echo base_url(); ?>js/main.js"></script>

Примечание. Я разместил этот код в конце страницы (в представлении footer.php).

Добавляем ссылку «Ответить» внизу каждого комментария. Для этого открываем шаблон комментариев (\application\views\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>
	</p>
	<p class="commentDescription">{description}</p>
	<p class="replyComment"><a href="#">Ответить</a></p>
<?php
if ($this->redux_auth->logged_in()) {
	echo '<p class="deleteComment">'.anchor('bugtracker/deletecomment/{id}', 'Удалить').'</p>';
}
?>
</div>

Ссылка создается в строке 7. Тут может возникнуть вопрос: «Почему в параметрах ссылки мы не указываем id комментария?». Дело в том, что с помощью jQuery мы можем легко получить родительский div (строка 1) и прочесть его атрибут id, в котором записан id комментария.

Теперь рассмотрим функцию, которая перемещает форму (файл main.js).

$(function() {
	//перемещаем форму
	$(".replyComment a").click(function() {
		var comment = $(this).parent().parent();
		var commentId = comment.attr("id");
		var id = Array();
		//в id[1] будет сохранен id комментария на который нужно ответить
		id = commentId.split('-');
		
		//перемещаем форму
		$("#fAddComment").appendTo(comment);
		
		//устанавливаем значение в поле parent_id
		$("#parent_id").val(id[1]);
		
		//добавляем ссылку "Отменить комментарий", клик по ней возвращает форму вниз страницы
		cancelComment = $("<p class=\"cancelComment\"><a href=\"#\">Отменить комментарий</a></p>");
		cancelComment.prependTo($("#fAddComment"));
		var cancelLink = cancelComment.children("a").get(0);
		$(cancelLink).click(function() {
			$("#parent_id").val("");
			$(this).parent().remove();
			$("#fAddComment").insertBefore("#footer");
			
			return false;
		});
		
		//предотвращает "скачки" страницы
		return false;
	});

	//подтверждение удаления бага
	$(".deleteBug a").click(function() {
		return confirm("Точно удалить?");
	});
	
	//подтверждение удаления комментария
	$(".deleteComment a").click(function() {
		return confirm("Будет удалена ветка комментариев начиная с данного. Удалить?");
	});
});

Рассмотрим как она работает.

Прежде всего, мы находим все ссылки, которые находятся внутри элементов с классом «replyComment» (т.е. наши ссылки «Ответить»), и назначаем им обработчик события onclick (строка 3).

При клике по ссылке начинает выполняться функция (строки 3-30). Алгоритм тут следующий.

1) Получаем родительский div и читаем его атрибут id (строки 4, 5).

2) Вырезаем из него номер комментария (с помощью функции split, строка 8).

3) Перемещаем форму. Для этого мы используем функцию appendTo из библиотеки jQuery. Элемент, к которому нужно добавить форму мы получили на 1-ом шаге.

4) Записываем значение в поле parent_id (строка 14).

5) Создаём ссылку «Отменить комментарий» и размещаем её в начале формы. Клик по ней вернет форму в исходное положение.

Без этой ссылки вернуть форму в исходное положение можно будет, только обновив страницу, а сделать это догадаются не все 😉 .

6) Находим ссыку «Отменить комментарий» и назначем ей обработчик события onclick (строки 19-26).

7) В этом обработчике мы сбрасываем значение скрытого поля parent_id, удаляем ссылку «Отменить комментарий» и возвращаем форму в исходное положение.

Как видите, принцип работы достаточно простой. А благодаря jQuery вся функция занимает меньше 20 строк (если убрать комментарии и пустые строки).

В завершение мы выполняем ещё два действия.

Назначаем обработчик события onclick для всех ссылок «Удалить» (строки 33-40). Теперь при попытке удаления бага или комментария (в администраторском режиме) будет появляться диалог с просьбой подтвердить действие.

На этом я закончу эту часть.

Демо версия баг трекера.

Если у вас есть желание поэкспериментировать я выложил демо версию баг трекера. Логин: vvv@ddd.sss, пароль: 111.
Можете не задумываясь вставлять или удалять любые данные, все равно у меня есть бекап базы 😉

Скачать

Также можно скачать архив с исходниками.

И, конечно, вы можете поделиться своими впечатлениями в комментариях 😉

  • еслb несколько раз нажимать «ОТветить» то начинает клонироваться форма, а именно ссылка отменить комментарий.

    • Спасибо! Исправил и в демо версии и в архиве.

  • еслb несколько раз нажимать «ОТветить» то начинает клонироваться форма, а именно ссылка отменить комментарий.

    • Спасибо! Исправил и в демо версии и в архиве.

  • bokko

    /**
    * Удаляет комментарий из БД (связанные комментарии
    * удаляются автоматически движком MySQL)
    *
    * @param $id - id комментария в таблице
    * @return TRUE - если комментарий удален, FALSE - в противном случае.
    */
    function delete($id) {
    if (is_integer($id) || $id db->query($qDel, array($id));
    }
    — сильно!

    if ( ! (int)$id) {
    return false;
    }

  • bokko

    /**
    * Удаляет комментарий из БД (связанные комментарии
    * удаляются автоматически движком MySQL)
    *
    * @param $id - id комментария в таблице
    * @return TRUE - если комментарий удален, FALSE - в противном случае.
    */
    function delete($id) {
    if (is_integer($id) || $id db->query($qDel, array($id));
    }
    — сильно!

    if ( ! (int)$id) {
    return false;
    }

  • bokko


    function bug($id = 1) {
    if (!is_integer((int)$id) || (int)$id <= 0) {
    redirect('bugtracker/index');
    return;
    }
    ...

    — вообще жесть!

    • А в чем вопрос? или замечание?
      Много проверок? или мало?
      Даже не знаю, что ответить 😉

      • Андрей

        Во первых что бросается в глаза — зачем делать return после redirect? Посмотрите код этой функции — там и так уже делается exit;. Во вторых — is_integer((int)$id — это условие будет всегда верно.
        Можно переделать так:
        function bug($id = 1) {
        if ((int)$id <= 0)
        redirect('bugtracker/index');
        }

        • зачем делать return после redirect?

          Перестраховался 🙂 На самом деле код я не смотрел.

          это условие будет всегда верно

          Согласен, тут я ошибся. (int) нужно убрать.

          В вашем варианте есть один нюанс. Проблема в том, что
          (int)'11d11' = 11
          т.е. при преобразовании типов PHP оставляет все символы до того как встретит некорректный (букву d).
          А я хотел убедиться, что ВСЯ строка, которая передается в параметре, является именно числом.

          В общем, должна подойти проверка вроде
          if (!is_integer($id) || (int)$id <= 0)

  • bokko


    function bug($id = 1) {
    if (!is_integer((int)$id) || (int)$id <= 0) {
    redirect('bugtracker/index');
    return;
    }
    ...

    — вообще жесть!

    • А в чем вопрос? или замечание?
      Много проверок? или мало?
      Даже не знаю, что ответить 😉

      • Андрей

        Во первых что бросается в глаза — зачем делать return после redirect? Посмотрите код этой функции — там и так уже делается exit;. Во вторых — is_integer((int)$id — это условие будет всегда верно.
        Можно переделать так:
        function bug($id = 1) {
        if ((int)$id <= 0)
        redirect('bugtracker/index');
        }

        • зачем делать return после redirect?

          Перестраховался 🙂 На самом деле код я не смотрел.

          это условие будет всегда верно

          Согласен, тут я ошибся. (int) нужно убрать.

          В вашем варианте есть один нюанс. Проблема в том, что
          (int)'11d11' = 11
          т.е. при преобразовании типов PHP оставляет все символы до того как встретит некорректный (букву d).
          А я хотел убедиться, что ВСЯ строка, которая передается в параметре, является именно числом.

          В общем, должна подойти проверка вроде
          if (!is_integer($id) || (int)$id < = 0)

  • ALEX

    Владимир, скажите пожалуйста а как корректно убрать поле имейл из данного багтрекера и заменить его на дополнительное текстовое?

    + инфо по архиву
    папку Images надо в архив включить и переименовать файлы в сss а то сразу не работает

  • ALEX

    Владимир, скажите пожалуйста а как корректно убрать поле имейл из данного багтрекера и заменить его на дополнительное текстовое?

    + инфо по архиву
    папку Images надо в архив включить и переименовать файлы в сss а то сразу не работает

  • ALEX

    + можно обьяснить как создавать дополнительно пользователя? я нашел закомментированный код но не разобрался

    • eMail:

      Примерно изменения будут такие:
      1) создаем новое поле в базе данных (поле с eMail можно убрать)
      2) изменяем форму в представлении (достаточно скопировать существующее поле и поменять name, id и т.д.)
      3) в контроллер добавить обработку нового поля (как минимум установить правила для нового поля
      $this->form_validation->set_rules…
      и добавить чтение нового поля
      $this->input->post…)
      4) исправить запрос в модели (нужно будет добавить запрос в новое поле, которое вы создали в БД)

      Создание пользователя.
      Добавить пользователя не сложно. Нужно раскомментировать тот код, который вы видели (метод register). В параметрах $this->redux_auth->register указать данные нового пользователя. После этого в браузере ввести URL
      http://yoursite/bugtracker/register
      После этого будет создан пользователь.
      Снова закомментировать метод.
      Если пользователей нужно добавлять постоянно, т.е. сделать регистрацию, то придется создать новую форму и соответствующий код в метод (проверку введенных полей, вывод сообщений об ошибках и т.д.).

  • ALEX

    + можно обьяснить как создавать дополнительно пользователя? я нашел закомментированный код но не разобрался

    • eMail:

      Примерно изменения будут такие:
      1) создаем новое поле в базе данных (поле с eMail можно убрать)
      2) изменяем форму в представлении (достаточно скопировать существующее поле и поменять name, id и т.д.)
      3) в контроллер добавить обработку нового поля (как минимум установить правила для нового поля
      $this->form_validation->set_rules…
      и добавить чтение нового поля
      $this->input->post…)
      4) исправить запрос в модели (нужно будет добавить запрос в новое поле, которое вы создали в БД)

      Создание пользователя.
      Добавить пользователя не сложно. Нужно раскомментировать тот код, который вы видели (метод register). В параметрах $this->redux_auth->register указать данные нового пользователя. После этого в браузере ввести URL
      http://yoursite/bugtracker/register
      После этого будет создан пользователь.
      Снова закомментировать метод.
      Если пользователей нужно добавлять постоянно, т.е. сделать регистрацию, то придется создать новую форму и соответствующий код в метод (проверку введенных полей, вывод сообщений об ошибках и т.д.).

  • Один из недостатков (недоработок) этого багтрекера — не поддерживаются префиксы таблиц. Я так понял, принципиально, из-за ручного составления запросов? Хотел поставить в дополнение к ещё одному приложению на CI — в одну базу и даже где-то интегрировавши, благо, схожая идеология в лице единого фреймворка позволяет.
    И первым же делом получил болт «Table 'my_base.bugs' doesn't exist»

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

    • не поддерживаются префиксы таблиц

      Честно говоря, просто упустил из виду.

      Поддержу добавить не сложно и, конечно, жестко прописывать префиксы не стоит.

      В конфиге (database.php) есть параметр
      $db['default']['dbprefix'] = «»;
      Он автоматически работает если используется Active Record.

      В ручную его можно получить так:
      $prefix = $this->db->dbprefix;
      После этого достаточно добавить $prefix к именам таблиц в запросах.
      SELECT * FROM $prefix.bugs WHERE …

      • А, понял, спасибо!
        Нет, переписывать под AR не буду. Добавлю назначение багам статусов «Исправлен», «Проигнорирован»… Как-то так.
        Ну, по мелочи, типа, отображать по умолчанию только неисправленные баги.
        Как раз и проект на CI, и в мощном трекере нет надобности (и желания). И практика.

        Кстати, Владимир, вы не думали как-то назвать этот трекер?
        Интересуюсь просто потому, что часто разработчики посылают:
        — На мантис!
        — Запиши на багзиллу.
        Etc. Мелочь, а хочется чего-то такого.

        • Этот проект задумывался как чисто академический (пример создания web приложения с использованием CodeIgniter). Т.е. создавать альтернативу какому-то существующему баг-трекеру я не собирался.

          Но мне очень приятно, что вам он пригодился 🙂

          О названии я не думал. Вариант вроде Simple Bug Tracker звучит как-то банально. Есть предложения?

    • Второй вариант — переписать запросы с использованием ActiveRecord.

  • Один из недостатков (недоработок) этого багтрекера — не поддерживаются префиксы таблиц. Я так понял, принципиально, из-за ручного составления запросов? Хотел поставить в дополнение к ещё одному приложению на CI — в одну базу и даже где-то интегрировавши, благо, схожая идеология в лице единого фреймворка позволяет.
    И первым же делом получил болт «Table 'my_base.bugs' doesn't exist»

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

    • не поддерживаются префиксы таблиц

      Честно говоря, просто упустил из виду.

      Поддержу добавить не сложно и, конечно, жестко прописывать префиксы не стоит.

      В конфиге (database.php) есть параметр
      $db['default']['dbprefix'] = «»;
      Он автоматически работает если используется Active Record.

      В ручную его можно получить так:
      $prefix = $this->db->dbprefix;
      После этого достаточно добавить $prefix к именам таблиц в запросах.
      SELECT * FROM $prefix.bugs WHERE …

      • А, понял, спасибо!
        Нет, переписывать под AR не буду. Добавлю назначение багам статусов «Исправлен», «Проигнорирован»… Как-то так.
        Ну, по мелочи, типа, отображать по умолчанию только неисправленные баги.
        Как раз и проект на CI, и в мощном трекере нет надобности (и желания). И практика.

        Кстати, Владимир, вы не думали как-то назвать этот трекер?
        Интересуюсь просто потому, что часто разработчики посылают:
        — На мантис!
        — Запиши на багзиллу.
        Etc. Мелочь, а хочется чего-то такого.

        • Этот проект задумывался как чисто академический (пример создания web приложения с использованием CodeIgniter). Т.е. создавать альтернативу какому-то существующему баг-трекеру я не собирался.

          Но мне очень приятно, что вам он пригодился 🙂

          О названии я не думал. Вариант вроде Simple Bug Tracker звучит как-то банально. Есть предложения?

    • Второй вариант — переписать запросы с использованием ActiveRecord.

  • — Родилось новое озеро, — тихо сказал Витааль. — Никогда не думал, что увижу такое чудо — озеро, созданное человеком. Одним человеком…
    — А название у него есть? — спросил лод Гвэйдеон.
    — Было… когда-то… Этого озера не существовало больше двух веков, его название давно забылось…
    — Тогда мы можем назвать его сами? — загорелись глаза Вон. Она давно мечтала украсить географическую карту собственным названием. — Можно?
    — Ну, полагаю, это должен сделать тот, кто его создал… — осторожно предположил Витааль. Ему тоже очень хотелось оставить след в мировой географии.
    Креол некоторое время думал, а потом равнодушно пожал плечами. Он получил, что хотел, и дальнейшее стало ему безразлично. Собственно, если бы это озеро прямо сейчас высохло бы снова, он и не подумал бы огорчаться.
    Поэтому вопрос о названии нового водоема пришлось решать остальным членам команды. И спорили они очень долго. Лод Гвэйдеон требовал увековечить Пречистую Деву или хотя бы святого Креола. Ванесса настаивала, чтобы озеро назвали в ее честь. Оснований на это у нее не было, но очень хотелось. Витааль считал, что нужно подобрать что-нибудь красивое, выразительное и отображающее великое деяние, свершенное здесь. Скажем, «Озеро Милости Архимага». Индрак, не любивший сложных названий, предложил простое — «Озеро С Водой». Ну а единственный вариант, выданный Логмиром, вряд ли пропустила бы цензура…
    Креол наблюдал за этим с явным неодобрением — не мог понять, зачем столько спорить из-за такой чепухи. А когда понял, что так они могут чесать языком весь день, решительно вмешался.
    — Тихо, — поднял руку он. — Сейчас я вас рассужу.
    Он достал из сумки самый обыкновенный игральный кубик. Шестигранный.
    — Один, два, три, четыре, пять, — произнес он, поочередно тыкая пальцем в каждого из товарищей. — Чей номер выпадет, тот и дает название.
    — А если выпадет шесть? — спросила «двойка».
    — Не знаю, — честно ответил Креол, бросая кубик.
    Выпало шесть.
    — Ну что, перебросим? — предложила Ванесса.
    — Нет, — отказался маг. — Я сам его назову. Нарекаю тебя… м-м-м… нарекаю… Ану Сотворитель, должно же быть хоть одно хорошее название!
    Вон нетерпеливо подпрыгивала, тяня вверх руку и стараясь обратить на себя внимание. Остальные терпеливо ожидали мудрого решения Креола. А тот тупо смотрел на низвергающийся водопад и ясно понимал, что в голове нет ничего, кроме откровенной ерунды, которой стыдно называть даже лужу. Креол никогда не умел давать названия.
    Пятью минутами спустя коцебу поднялся в воздух, оставляя за собой новое озеро.
    Безымянное Озеро.

    © А.Рудазов — из цикла «Архимаг» 🙂

    • 100% в тему 🙂
      Безымянный багтрекер.
      Nameless BugTracker.
      Почему бы и нет? Название безусловно оригинальное 🙂

  • — Родилось новое озеро, — тихо сказал Витааль. — Никогда не думал, что увижу такое чудо — озеро, созданное человеком. Одним человеком…
    — А название у него есть? — спросил лод Гвэйдеон.
    — Было… когда-то… Этого озера не существовало больше двух веков, его название давно забылось…
    — Тогда мы можем назвать его сами? — загорелись глаза Вон. Она давно мечтала украсить географическую карту собственным названием. — Можно?
    — Ну, полагаю, это должен сделать тот, кто его создал… — осторожно предположил Витааль. Ему тоже очень хотелось оставить след в мировой географии.
    Креол некоторое время думал, а потом равнодушно пожал плечами. Он получил, что хотел, и дальнейшее стало ему безразлично. Собственно, если бы это озеро прямо сейчас высохло бы снова, он и не подумал бы огорчаться.
    Поэтому вопрос о названии нового водоема пришлось решать остальным членам команды. И спорили они очень долго. Лод Гвэйдеон требовал увековечить Пречистую Деву или хотя бы святого Креола. Ванесса настаивала, чтобы озеро назвали в ее честь. Оснований на это у нее не было, но очень хотелось. Витааль считал, что нужно подобрать что-нибудь красивое, выразительное и отображающее великое деяние, свершенное здесь. Скажем, «Озеро Милости Архимага». Индрак, не любивший сложных названий, предложил простое — «Озеро С Водой». Ну а единственный вариант, выданный Логмиром, вряд ли пропустила бы цензура…
    Креол наблюдал за этим с явным неодобрением — не мог понять, зачем столько спорить из-за такой чепухи. А когда понял, что так они могут чесать языком весь день, решительно вмешался.
    — Тихо, — поднял руку он. — Сейчас я вас рассужу.
    Он достал из сумки самый обыкновенный игральный кубик. Шестигранный.
    — Один, два, три, четыре, пять, — произнес он, поочередно тыкая пальцем в каждого из товарищей. — Чей номер выпадет, тот и дает название.
    — А если выпадет шесть? — спросила «двойка».
    — Не знаю, — честно ответил Креол, бросая кубик.
    Выпало шесть.
    — Ну что, перебросим? — предложила Ванесса.
    — Нет, — отказался маг. — Я сам его назову. Нарекаю тебя… м-м-м… нарекаю… Ану Сотворитель, должно же быть хоть одно хорошее название!
    Вон нетерпеливо подпрыгивала, тяня вверх руку и стараясь обратить на себя внимание. Остальные терпеливо ожидали мудрого решения Креола. А тот тупо смотрел на низвергающийся водопад и ясно понимал, что в голове нет ничего, кроме откровенной ерунды, которой стыдно называть даже лужу. Креол никогда не умел давать названия.
    Пятью минутами спустя коцебу поднялся в воздух, оставляя за собой новое озеро.
    Безымянное Озеро.

    © А.Рудазов — из цикла «Архимаг» 🙂

    • 100% в тему 🙂
      Безымянный багтрекер.
      Nameless BugTracker.
      Почему бы и нет? Название безусловно оригинальное 🙂

  • Александр

    Читал, читал статьи в предвкушении того как на это всё дело будет ajax навешиваться… но так и не дождался :((((

    • Согласен, обещание я действительно не выполнил.
      Мне пришлось изменить первоначальный план, но не из-за технических проблем.
      Первоначально я планировал использовать только AJAX, но мне быстро объяснили, что это не правильно, т.к. страницы не будут индексироваться поисковиками. Поэтому получается, что навигацию с использованием AJAX делать нельзя, остаются только формы добавления бага и комментария. Но поработав с приложением мне расхотелось вешать на эти формы AJAX.

      Преимущества мне кажется будут минимальные (для пользователя).
      Если вы не согласны или есть предложения (в смысле расширения функционала), я готов выслушать и обсудить 😉

  • Александр

    Читал, читал статьи в предвкушении того как на это всё дело будет ajax навешиваться… но так и не дождался :((((

    • Согласен, обещание я действительно не выполнил.
      Мне пришлось изменить первоначальный план, но не из-за технических проблем.
      Первоначально я планировал использовать только AJAX, но мне быстро объяснили, что это не правильно, т.к. страницы не будут индексироваться поисковиками. Поэтому получается, что навигацию с использованием AJAX делать нельзя, остаются только формы добавления бага и комментария. Но поработав с приложением мне расхотелось вешать на эти формы AJAX.

      Преимущества мне кажется будут минимальные (для пользователя).
      Если вы не согласны или есть предложения (в смысле расширения функционала), я готов выслушать и обсудить 😉

  • Александр

    а какже постепенное улучшение? Как прикрутить сюда ajax я посоветовать не могу поскольку и пришёл сюда узнать как правильно это делать, чтоб и без явы работало и те у кого ява включена ощущали её силу 🙂
    А вот какой вункционал прикрутить..
    Ну вот например перелистывание страничек с багами без перезагрузки страничек, фильтровать по категории, оставлять коммент..

    • «Прикрутить» ajax не сложно.
      1) На стороне сервера (php) добавляем метод в контроллер (вроде ajaxaddcomment), который работает так же как и addcomment, только возвращает не новую страницу, а результат выполнения операции (например, «OK» или «ERR»).
      2) На стороне клиента вешаем обработчик события click на соответствующую ссылку или кнопку. При этом этот обработчик должен возвращать false (return false), чтобы заблокировать отправку запроса обычным способом. Внутри обработчика формируем и отправляем запрос к ajaxaddcomment и обрабатываем его результат.

      Т.е. технически ничего сложного. Проблема в другом. В этом конкретном приложении использование ajax практически не даёт преимуществ, т.е. «улучшения» не будет.
      Например, при перелистывании страничек и фильтрации по категориям мы должны отправить список всех багов для этой страницы, точно также как и при обработке обычного запроса.
      Преимущество есть при добавлении/удалении комментариев, если их много. Для страниц с двумя-тремя комментариями это преимущество опять же сводится на нет, особенно если учесть, что к размеру страницы добавится размер скриптов.

  • Александр

    а какже постепенное улучшение? Как прикрутить сюда ajax я посоветовать не могу поскольку и пришёл сюда узнать как правильно это делать, чтоб и без явы работало и те у кого ява включена ощущали её силу 🙂
    А вот какой вункционал прикрутить..
    Ну вот например перелистывание страничек с багами без перезагрузки страничек, фильтровать по категории, оставлять коммент..

    • «Прикрутить» ajax не сложно.
      1) На стороне сервера (php) добавляем метод в контроллер (вроде ajaxaddcomment), который работает так же как и addcomment, только возвращает не новую страницу, а результат выполнения операции (например, «OK» или «ERR»).
      2) На стороне клиента вешаем обработчик события click на соответствующую ссылку или кнопку. При этом этот обработчик должен возвращать false (return false), чтобы заблокировать отправку запроса обычным способом. Внутри обработчика формируем и отправляем запрос к ajaxaddcomment и обрабатываем его результат.

      Т.е. технически ничего сложного. Проблема в другом. В этом конкретном приложении использование ajax практически не даёт преимуществ, т.е. «улучшения» не будет.
      Например, при перелистывании страничек и фильтрации по категориям мы должны отправить список всех багов для этой страницы, точно также как и при обработке обычного запроса.
      Преимущество есть при добавлении/удалении комментариев, если их много. Для страниц с двумя-тремя комментариями это преимущество опять же сводится на нет, особенно если учесть, что к размеру страницы добавится размер скриптов.

  • Тимофей

    мм… классика жанра
    хотелось бы высказаться по поводу ф-ла

    лювые списки имхо должны содержать како

  • Тимофей

    мм… классика жанра
    хотелось бы высказаться по поводу ф-ла

    лювые списки имхо должны содержать како

  • Тимофей

    сори … поспешил 🙁

    … какой нить фильтр
    пока есть только по категории и по кол-ву элемиентов на странице
    было бы полезно еще по автору фильтровать, по дате и тд

    ну и где же преславутые статусы? или же настройка схемы перемещения баги в другую категорию — например категория исправленные
    хотя это должно быть отдельно — в виде статуса

    • Я уже писал, я не пытался сделать полнофункциональный баг трекер. Это _пример_ создания web приложения. Я специально до минимума сократил количество функций.

  • Тимофей

    сори … поспешил 🙁

    … какой нить фильтр
    пока есть только по категории и по кол-ву элемиентов на странице
    было бы полезно еще по автору фильтровать, по дате и тд

    ну и где же преславутые статусы? или же настройка схемы перемещения баги в другую категорию — например категория исправленные
    хотя это должно быть отдельно — в виде статуса

    • Я уже писал, я не пытался сделать полнофункциональный баг трекер. Это _пример_ создания web приложения. Я специально до минимума сократил количество функций.

  • DarkSkeleton

    Попробовал этот баг трекер, сделал все по инструкции, но после импортирования бекап базы, при заходе вылетает ошибка:

    Ошибка БД
    Error Number: 1364

    Field 'user_data' doesn't have a default value

    INSERT INTO `sessions` (`session_id`, `ip_address`, `user_agent`, `last_activity`) VALUES ('585d84e43fa499b1147c1752c8597b4a', '127.0.0.1', 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1;', 1260960485)

    Может я что то делаю не так?

  • DarkSkeleton

    Попробовал этот баг трекер, сделал все по инструкции, но после импортирования бекап базы, при заходе вылетает ошибка:

    Ошибка БД
    Error Number: 1364

    Field 'user_data' doesn't have a default value

    INSERT INTO `sessions` (`session_id`, `ip_address`, `user_agent`, `last_activity`) VALUES ('585d84e43fa499b1147c1752c8597b4a', '127.0.0.1', 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1;', 1260960485)

    Может я что то делаю не так?

  • Я думаю, в вашем случае проще всего будет разрешить записывать значение NULL в поле user_data (таблица sessions) (можно изменить через phpMyAdmin).
    Кроме того, на форуме CI есть топик на эту тему.

  • Я думаю, в вашем случае проще всего будет разрешить записывать значение NULL в поле user_data (таблица sessions) (можно изменить через phpMyAdmin).
    Кроме того, на форуме CI есть топик на эту тему.

  • на денвере при добавлении записи ругается
    Message: file_get_contents(Z:homebugswwwsystemapplicationlibrarieshtmlpurifier/HTMLPurifier/ConfigSchema/schema.ser) [function.file-get-contents]: failed to open stream: No such file or directory

    в пути слэши и прямые и обратные одновременно
    где исправить косяк ?

    и ещё в дистрибутиве
    general.css надо переименовывать в general-min.css
    reset тоже

    • :-DDD
      Косяк исправлять в винде! На юниксах путь как и положено юниксовый.
      Ну, не считая того, что схему нужно положить по указанному пути.

    • Как-то странно. Я использую WAMPSERVER (тоже винда), подобных проблем никогда не было. HTMLPurifier это внешняя библиотека, используется для «очистки» входящих данных.
      Очень советую попробовать поставить Apache + PHP со стандартными настройками и посмотреть как будет работать.

    • Dm

      у меня в архиве вообще не было файла «schema.ser»..
      скачал новую версию «htmlpurifier» и добавил в старую версию, но всё равно остались кучи ошибок…
      заменил все файлы «htmlpurifier» новой версии, но к сожалению при добавлении комментария показывается белый экран и ничего не происходит..
      подскажите как исправить??

      • Dm

        пока просто закомментировал строки

        #$this->load->library('htmlpurifier/HTMLPurifier');
        #$config = HTMLPurifier_Config::createDefault();

        и при «$this->htmlpurifier->purify» убрал, и всё работает…
        это чем-то чревато?

        • HTMLPurifier убирает потенциально опасные теги из текста, например, тег script, т.е. чревато XSS уязвимостью.

          Файл schema.ser должен быть в папке
          libraryHTMLPurifierConfigSchema

          Проверьте размещение библиотеки.

          И напишите, какие именно ошибки возникали.

  • на денвере при добавлении записи ругается
    Message: file_get_contents(Z:\home\bugs\www\system\application\libraries\htmlpurifier/HTMLPurifier/ConfigSchema/schema.ser) [function.file-get-contents]: failed to open stream: No such file or directory

    в пути слэши и прямые и обратные одновременно
    где исправить косяк ?

    и ещё в дистрибутиве
    general.css надо переименовывать в general-min.css
    reset тоже

    • :-DDD
      Косяк исправлять в винде! На юниксах путь как и положено юниксовый.
      Ну, не считая того, что схему нужно положить по указанному пути.

    • Как-то странно. Я использую WAMPSERVER (тоже винда), подобных проблем никогда не было. HTMLPurifier это внешняя библиотека, используется для «очистки» входящих данных.
      Очень советую попробовать поставить Apache + PHP со стандартными настройками и посмотреть как будет работать.

  • В демке в упор не вижу возможности комментирования багов !!!
    где ссылка «Ответить» внизу каждого комментария ?

  • В демке в упор не вижу возможности комментирования багов !!!
    где ссылка «Ответить» внизу каждого комментария ?

  • Кликаете по нужному багу, под ним будут все комментарии, которые к нему относятся. Под каждым комментарием ссылка «Ответить».

    http://screencast.com/t/OWI1YWMwZjg

  • Кликаете по нужному багу, под ним будут все комментарии, которые к нему относятся. Под каждым комментарием ссылка «Ответить».

    http://screencast.com/t/OWI1YWMwZjg

  • ммда уж, фиг догадаешься что нужно на тайтл бага тыкать 🙂

    • Тогда вопрос к вам 🙂 В каком виде лучше оформить список багов, чтоб было понятнее?

  • ммда уж, фиг догадаешься что нужно на тайтл бага тыкать 🙂

    • Тогда вопрос к вам 🙂 В каком виде лучше оформить список багов, чтоб было понятнее?

  • Pingback: И снова о CodeIgniter (PHP фреймворк) | Заработок в интернете - о способах и инструментах()

  • гость

    вопрос не по теме — как из контроллера передать переменную в модель?

  • Просто объявите в модели метод, который принимает параметры и передавайте в них свои данные. Здесь есть пример (метод getClusteredCloud).

    • Pavel

      Владимир, демо версия не работает:(((

      • Огромное спасибо, что сообщили!
        Я недавно переносил сайты на другой сервер. И таки упустил этот из виду.
        Все исправил.