Если вы дочитали цикл про создание компонента с нуля на Joomla до этой статьи, то вы скорее всего уже пробовали что-то создать. И как в любом нормальном программном продукте, в вашем, используется база данных. В базе соответственно есть некие записи. Выводить их мы научились в прошлой статье. А как же их туда вносить? Об этом и поговорим ниже.
о идее, в системах на MVC за такие действия должна отвечать модель. А контроллер лишь передает ей указания. Мы пока не работаем с моделями, поэтому все будем делать в контроллере. Так будет проще и наглядней. И по секрету скажу, что 90% программистов так и делают. А еще 5, хоть и пытаются всю логику с БД засунуть в модель, все равно делают часть работы в контроллере. Это вообще тема отдельной статьи. Как-нибудь напишу, как работать с моделями в Yii и что это вообще такое - модели. Дело в том, что зачастую программисты не читают первоисточники на английском языке, а довольствуются лишь крупицами переведенной информации. Между тем, получить хороший перевод за разумные деньги можно довольно просто, достаточно найти бюро Дока в Москве, и ребята все сделают за вас. Но я отошел от темы. Вернемся к нашему компоненту.
Итак к примеру у нас есть такая табличка
CREATE TABLE IF NOT EXISTS `jml_votes` ( `id` int(11) NOT NULL AUTO_INCREMENT, `ip` varchar(30) DEFAULT NULL, `contentid` int(11) NOT NULL, PRIMARY KEY (`id`), KEY `contentid` (`contentid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
В таблице содержатся факт голосования, отдал ли пользователь за ту или иную статью свой голос. Голос может быть как положительным так и отрицательным. Один и тот же пользователь, не может отдать два раза голос за одну и ту же статью. Блокировать будем на основе ip пользователя.
Сами голоса, а точнее их количество содержаться в поле votes таблицы jml_content. По умолчанию в Joomla такого поля нет. Сделаем его
ALTER TABLE `jml_content` ADD `votes` INT NOT NULL
Теперь нам нужно эти самые голоса отправлять. Вставим в любое место нашего шаблона пару ссылок
<div class="voter"> <a href="javascript:void(0);" onclick="vote.call(this,('up',<?=$id?>);" class="voter_up">up</a> <a href="javascript:void(0);" onclick="vote.call(this,'down',<?=$id?>);" class="voter_down">down</a> <span><?=$votes?></span> </div>
Как их оформить внешне, решать вам. В своем проекте, я сделал в виде традиционных кулачков, вверх и вниз.
Теперь надо написать функцию vote
function vote(arrow,id){ jQuery.post('/index.php?option=com_moy_component&task=vote',{id:id,arrow:arrow},function(resp){ if(resp.res==1){ jQuery('.voter a').remove(); jQuery('.voter span').html(resp.msg); } } ,'json'); }
Обратите внимание на последний параметр метода post. Он говорит jQuery, что будет использоваться JSON ответ. Я использую в своем проекте jQuery. Чтобы эта библиотека заработала в Joomla надо подключать ее в режиме
jQuery.noConflict();
Конечно, все зависит от шаблона. Но лишним не будет.
Итак, мы послали данные на сервере. Теперь надо их обработать в контроллере
function vote(){ if( !uno::exists('content','id='.intval($_REQUEST['id'])) ) exit(json_encode(array('res'=>0,'msg'=>'content not found'))); if( uno::exists('votes',array('contentid='.intval($_REQUEST['id']),'ip='.uno::_($this->myip()))) ) exit(json_encode(array('res'=>0,'msg'=>'you already voted'))); uno::insert('votes',array('contentid'=>intval($_REQUEST['id']),'ip'=>$this->myip())); uno::update('content',array('votes=votes'.($_REQUEST['arrow']=='up'?'+':'-').'1'),'id='.intval($_REQUEST['id'])); $ball = uno::exists('content','id='.intval($_REQUEST['id']),'votes'); exit(json_encode(array('res'=>1,'msg'=>$ball))); }
Я вновь использовал класс uno. По моему он очень удобен. Что же му туту сделали: проверяем есть ли такой материал, проверяем голосовали ли уже. Если все ок, заносим в votes факт голосования с нашего ip за этот материал, и обновляем общее количество баллов. В ответ вносим новый балл (вдруг, пока мы думали, кто-то проголосовал за эту же статью)
осталось только написать метод myip
private function myIP(){ $ipa = explode( ',',@$_SERVER['HTTP_X_FORWARDED_FOR'] ); return isset($_SERVER['HTTP_X_REAL_IP'])?$_SERVER['HTTP_X_REAL_IP']:(isset($_SERVER['REMOTE_ADDR'])?$_SERVER['REMOTE_ADDR']:(!empty($ipa[0])?$ipa[0]:'92.50.156.138')); }
Вот и все.
Создание компонента Joomla с нуля
Комментарии
Открываем доки https://docs.joomla.org/Retrieving_request_data_using_JInput и видим что есть бесполезная регулярка, которая делает ровно то же что и intval