Глава 8. Создание новых узлов программным способом
Мы достаточно уже узнали о том, как производить выборку узлов для отображения на странице. В этой главе мы попробуем создать новый узел прямо из нашего собственного метода. Нашей задачей на этот раз будет обеспечение возможности добавления комментария к произвольной новости. На страницу, отображающую текст новости (напомним, что это метод /news/news_post/show, который мы создали в Главе 4), мы поместим простую форму для добавления комментария. При этом мы упростим задачу, отказавшись от проверок на спам-роботов, и условимся, что комментарий может добавить любой посетитель сайта. Для добавления комментария посетитель должен указать свое имя и текст комментария и нажать на кнопку "Отправить". Страница при этом перезагружается и посетитель сразу видит свой комментарий под текстом новости. Когда посетитель нажимаем на кнопку "Отправить", введенное им имя и текст отправляются на сервер в созданный нами метод, который добавляет узел типа "Комментарий" и перенаправляет пользователя обратно на страницу новости.
Прежде всего созадим в модуле "Новости" новый тип под название "comment" и псевдонимом "Комментарий". У этого типа поле "NName" будет служить для хранения имени посетителя, а для текста его сообщения мы добавим поле "Text" (псевдоним "Текст") типа "plain_text". В типе "Новостное сообщение" отметим галочкой флажок "Является группой" и укажем, что в качестве дочерних узлов в данный тип могут вкладываться узлы типа "Комментарий".
Теперь можно добавить код формы для отсылки комментария, а также цикл для вывода комментариев пользователей. Шаблон метода /news/news_post/show, описанный в Листинге 5, будет теперь выглядеть следующим образом:
Добавим метод для обработки данных, пришедших из формы. Назовем метод "add_comment" и прикрепим его к типу "Новость". Таким образом его URL будет выглядеть как "/news/news_post/add_comment/". Это метод будет состоять только из процессора, поскольку он не должен выводить никаких данных, его основная задача - добавить новый узел и перенаправить пользователя на метод "/news/news_post/show".
Через массив $_POST, как и в обычном PHP-скрипте, в наш процессор передаются все данные формы, отправленной методом POST. Если данные не пустые, мы используем функцию xs2InsertNode из XS2 API для добавления нового узла типа "Комментарий", и если добавление прошло успешно, перенаправляем пользователя обратно на страницу новости. Следует обратить внимание, что функция xs2InsertNode доступна только в процессоре. Здесь необходимо сделать небольшое отступление.
Функции выборки узлов, такие как xs2GetNodes, доступны как в шаблоне, так и в процессоре, в то время, как функции, изменяющие узлы (xs2InsertNode, xs2UpdateNode и др.), - только в процессоре. Чем отличается использование функции XS2 API в процессоре от использования ее в шаблоне? Отличие чисто синтаксическое. Давайте сравним два вызова функции xs2GetNodes:
В шаблоне Smarty
{xs2GetNodes mod="news" NType="news_post" sort="Date desc" limit=3 var="my_news"}
В процессоре PHP
$my_news = xs2GetNodes(array('mod'=>'news','NType'=>'news_post','sort'=>'Date desc','limit'=>3));
Как видим, отличие абсолютно регулярно, т.е. зная, как выглядит вызов в Smarty, можно точно сказать, как будет выглядеть вызов в процессоре, и наоборот. Важно отметить, что для удобства функции XS2 API в PHP принимают всегда только один параметр типа array, в котором с помощью пар "ключ=>значение" передаются все необходимые атрибуты. Также стоит обратить внимание, что в шаблоне Smarty результат выполнения функции назначается в переменную, название которой указано в параметре var, а в PHP, как и следовало ожидать, результат возвращается самой функцией.
Возвращаясь к вызову xs2InsertNode в нашем процессоре, обратим внимание, что в качестве единственного параметра ей передается массив, содержащий в виде пар "ключ=>значение" поля вставляемого узла. Ключ содержит название поля, значение - данные, которые в это поле вставляются. При добавлении необходимо обязательно указывать следующие поля:
mod - название модуля, в который добавляется новый узел;
ParId - идентификатор узла, в который производится добавление нового узла. В нашем случае мы добавляем комментарий в конкретную новость, поэтому мы назначаем в ParId идентификатор новости, переданный через скрытое поле "news_post_id". Если добавление узла производится непосредственно в корень модуля, то в ParId необходимо указать значение 1. 1 - это фиксированный идентификатор корневого узла любого модуля.
NType - тип добавляемого узла. В нашем случае - "comment".
NFlag - видимость узла. 1 - узел виден, 2 - узел не виден. Мы хотим, чтобы комментарий был виден на сайте сразу после добавления, поэтому указываем параметр NFlag равный 1.
Все остальные поля узла могут быть заполнены по усмотрению разработчика. В нашем случае, мы заполняем также поля "NName" (автор комментария) и "Text" (текст комментария).
Функция xs2InsertNode при успешном завершении возвращает идентификатор созданного узла. Если идентификатор не вернулся, мы сообщаем пользователю об ошибке.
Теперь мы можем протестировать нашу форму. На главной странице выберем любую новость и перейдем на ее страницу. Заполним форму для комментария и нажмем на кнопку "Отправить". После перезагрузки страницы мы должны увидеть наш комментарий под текстом новости.