Реализация пользовательского модуля опроса

 

Всем доброго времени суток! Спасибо что заглянули на мой блог! Сегодня мы продолжим цикл статей "Создать блог с нуля", а именно продолжим создавать модуль опроса для нашего движка. Нам осталось реализовать пользовательскую часть. Сегодня нам предстоит написать три функции, два шаблона и обработчик

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

Третья функция будет решать какие из окон загрузить и показать пользователю

 

 

Не считая некоторых особенностей, некоторых функций, весь процесс реализации прост (как обычно =))

 

Для новоприбывших

 

Небольшая сноска для тех кто на блоге в первый раз. Данный материал рассчитан для читателей цикла статей "Создать блог с нуля". Данный цикл повествуют о создание своего движка персонального блога. По сути данный "курс" можно назвать практическими уроками php

Если Вам интересны данные статьи, то переходите по ссылке, что я дал Вам выше, и приступайте к изучению. Если Вы собираетесь задержаться на моем блоге, то предлагаю Вам подписаться на RSS ленту блога через ридер, или же по почте.

 

Шаблоны окон опроса

 

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

 

Шаблон для формы опроса - pollFORM.html

 

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

					<!--ОПРОС-->
<div class="menu_title">Опрос</div>
<form id="f_poll" action="index.php" method="post" name="f_poll">
<table style="margin-left:16px;" width="162px" width="100%" cellpadding="3" cellspacing="0" border="0">
<tr>
<td colspan="2" align="center">[_qu]</td>
</tr>
[_while]
<tr>
<td width="20px" style="padding:5px;border-bottom:1px solid #dcdcdc;"><input type="radio" name="quePOLL" value="[_sub]"[_checked]/></td>
<td style="padding:5px;border-bottom:1px solid #dcdcdc;">[_val]</td>
</tr>
[_while]
<tr>
<td colspan="2" align="center" style="padding-top:15px;"><input class="sub" type="submit" value="Голосовать"></td>
</tr>
<tr>
<td colspan="2" align="center">
<div style="cursor:pointer;" onclick="document.getElementById('queRESULT').style.display = 'block';document.getElementById('queFORM').style.display = 'none';">Результат</div>
</td>
</tr>
</table>
</form>
<!--ОПРОС-->

Пожалуй главная проблема в данном шаблоне это сам дизайн. По этому поводу слишком не заморачивайтесь, сейчас дизайн не самое важное.

Страницы обработки (атрибут action) не имеет важной роли, но так как совершенно не известно с какой именно страницы будет голосовать пользователь, я выбрал вариант с главной страницей блога. На этой странице скрипт будет работать, и это главное =)

В данном шаблоне я использовал следующие код-слова:

  • [_qu] - Это код-слово будет заменено на вопрос опроса
  • [_sub] - Это очень важное код-слово. Является значением атрибута value у радио кнопки формы. Данное код-слово будет заменено на число от нуля до n. Думаю есть смысл пояснить почему именно на число. Значение радио кнопки поможет нам распознать к какому элементу массива прибавлять голос.

Пример: предположим у нас есть опрос с двумя вариантами ответа. Голоса в базе данных содержатся вот в таком виде:

0|0

В шаблоне будут две радио кнопки:

  1. первая имеет значение ноль
  2. вторая - единицу

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

$массив[0] - содержит 0

$массив[1] - содержит 0

скрипту не составит труда определить к какому элементу массива прибавлять голос, а именно к $массив[0], так как пользователь выбрал первый вариант (с значением ноль)

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

1|0

Надеюсь понятно =)

  • [_checked] - заменяется на значение checked для первого варианта ответа, и заменяется н пустоту для остальных. Необходимо для того чтобы первый вариант ответа (радио кнопка) был автоматически выбран
  • [_val] - Вариант ответа
  • [_while]...[_while] - Кусочек кода который скрипт вырежет и будет циклить (размножать =))

Данный шаблон я сохранил в пользовательской папке templates, с именем pollFORM.html

 

Шаблон для результата опроса - poll.html

					<!--РЕЗУЛЬТАТ-->
<div class="menu_title">Результат</div>
<table style="margin-left:16px;" width="162px" cellpadding="3" cellspacing="0" border="0" width="100%">
<tr>
<td colspan="2" align="center">[_qu]</td>
</tr>
[_while]
<tr>
<td width="20px" style="padding:5px;border-bottom:1px solid #dcdcdc;">[_kol]</td>
<td style="padding:5px;border-bottom:1px solid #dcdcdc;">[_val]</td>
</tr>
[_while]
<tr>
<td colspan="2" align="right" style="padding-top:15px;">Всего: [_all]</td>
</tr>
<tr>
<td colspan="2" align="center">
[_bottom]<div style="cursor:pointer;" onclick="document.getElementById('queRESULT').style.display = 'none';document.getElementById('queFORM').style.display = 'block';">К опросу</div>[_bottom]
</td>
</tr>
</table>
<!--РЕЗУЛЬТАТ-->

Использованы следующие код-слова:

  • [_qu] - вопрос
  • [_while]...[_while] - кусочек кода который скрипт вырежет и будет размножать
  • [_kol] - количество голосов за определенный вариант ответа
  • [_val] - вариант ответа
  • [_all] - общее количество голосов
  • [_bottom]...[_bottom] - кнопка "К опросу". Данные код-слова будут либо просто удаляться из шаблона, либо удаляться вместе с кнопкой

Данный шаблон я сохранил в пользовательской папке templates, с именем poll.html

 

Пользовательский модуль опроса для нашего движка - poll.php

 

Я уже не раз говорил что модуль будет содержать три функции и обработчик, но я забыл упомянуть еще одну очень важную вещь. Скрипт так же должен определить имя куки. Имя куки, для каждого опроса, должно быть свое, поэтому я, для формирования имени, использовал идентификатор (id) опроса. Таким образом для нашего первого опроса имя куки будет вот таким: quest_1

Давайте я сразу назову имена всех трех функций, так проще будет ориентироваться дальше:

  1. poll() - главная функция определяющая какие окна необходимо загрузить. У функции будет параметр (step), с помощью которого мы и будем определять какие окна грузить.
  2. opros() - функция генерирующая форму опроса. Для генерации нам понадобится массив содержащий варианты ответа и переменная содержащая вопрос.
  3. resultQUE() - функция генерирующая окно с результатами. Для формирования данного окна нам понадобится массивы с вариантами ответов и голосов, так же переменная с вопросом и параметр (step) определяющий убрать кнопку "К опросу" или нет.

Теперь создаем файл poll.php, в пользовательской папке moduls, и пишем наши функции

 

Главная функция - poll()

 

Данная функция будет определять какие окна опроса необходимо загрузить. Вот код функции

function poll($step)//сбор блока с опросом
{
$result_index = mysql_query("SELECT * FROM poll WHERE activ = '1'");//выводим из базы данных активный опрос
$myrow_index = mysql_fetch_array($result_index);

if($myrow_index != "")//если опрос есть
{
//делаем из строк value И otvet массивы
$val = explode("|",$myrow_index['value']);
$kol = explode("|",$myrow_index['otvet']);

if($step == 0)//если куки нет, значит скрипту нужно загрузить и форму и результаты
{
//дивы позволяют присвоить к окнам результата и опроса стиль display:none и display:block.
//Плюс к этому присваивается id который необходим для скрипта javascript
//который меняет стиль display:none на display:block и обратно
$result = "<div id=\"queFORM\" style=\"display:block;\">".opros($val,$myrow_index['que'])."</div>";

//функция результатом которой является результат опроса,
//запускается в режиме при котором в шаблоне останется кнопку "К опросу"
$result .= "<div id=\"queRESULT\" style=\"display:none;\">".resultQUE($val,$kol,$myrow_index['que'],0)."</div>";
}
else $result = resultQUE($val,$kol,$myrow_index['que'],1);//если кука есть то запускается
//только функция, результат которой будет результат опроса.
//При этом функция вырежет из шаблона кнопку "К опросу"
}

return $result;//выводим результат на экран пользователя
}

Код за комментирован так что проблем с пониманием возникнуть не должно. Единственное что хочу добавить это то, что переменная step примет свое значение в файле index.php. Именно в главном файле движка мы будем проверять есть ли кука. Если она есть то переменная step будет равна единице, если же куки нет то нулю.

 

Функция формирования формы опроса - opros()

 

Вот код функции:

function opros($val,$que)//форма опроса
{
//подключаем шаблон с формой
$sm_read = file("templates/pollFORM.html");
$sm_read = implode("",$sm_read);

$sm_read = str_replace("[_qu]",$que,$sm_read);//вставляем в шаблон вопрос
preg_match("/\[_while\](.*?)\[_while\]/s",$sm_read,$a);//вырезаем часть шаблона которую будем циклить

for($i=0;isset($val[$i]);$i++)//цикл формирования строк с вариантами ответа
{
$edd_tamp = $a[1];//копируем ту часть которую необходимо циклить (строка)

//если это первый шаг цикла то вставляем атрибут checked для первого варианта ответа
if($i == 0)$edd_tamp = str_replace("[_checked]"," checked",$edd_tamp);
//если последующие шаги то заменяем код-слово на пустоту
else $edd_tamp = str_replace("[_checked]","",$edd_tamp);

$edd_tamp = str_replace("[_sub]",$i,$edd_tamp);//значение value у радио кнопки
$edd_tamp = str_replace("[_val]",$val[$i],$edd_tamp);//вариант ответа
$poll .= $edd_tamp;//склеиваем все в одну переменную
}
$sm_read = preg_replace("/\[_while\].*?\[_while\]/s",$poll,$sm_read);//вставляем с генерированные строки в шаблон

return $sm_read;//выводим результат
}

Логику функции я пояснял не раз, так что добавить тут мне нечего. Функцию необходимо поместить сразу после функции poll()

 

Функция формирования результата опроса - resultQUE()

 

Вот код функции

function resultQUE($val,$kol,$que,$step)//результат
{
//подключаем шаблон с результатами
$sm_read = file("templates/poll.html");
$sm_read = implode("",$sm_read);

$sm_read = str_replace("[_qu]",$que,$sm_read);//вставляем в шаблон вопрос
preg_match("/\[_while\](.*?)\[_while\]/s",$sm_read,$a);//вырезаем часть шаблона которую будем циклить

$all = 0;//создаем переменную в которой будем считать общее кол-во голосов
for($i=0;isset($val[$i]);$i++)//цикл формирования строк с кол-вом голосов и вариантами ответа
{
$edd_tamp = $a[1];//копируем ту часть которую необходимо циклить (строка)

$edd_tamp = str_replace("[_kol]",$kol[$i],$edd_tamp);//число голосов
$edd_tamp = str_replace("[_val]",$val[$i],$edd_tamp);//варианты ответа

$all = $all + $kol[$i];//складываем количества голосов

$poll .= $edd_tamp;//склеиваем строки в оду переменную
}

$sm_read = str_replace("[_all]",$all,$sm_read);//заменяем код-слово на общее кол-во голосов

if($step == 0)$sm_read = str_replace("[_bottom]","",$sm_read);//если нет куки то оставляем кнопку "К опросу"
else $sm_read = preg_replace("/\[_bottom\].*?\[_bottom\]/s","",$sm_read);//если есть кука то удаляем кнопку "К опросу"

$sm_read = preg_replace("/\[_while\].*?\[_while\]/s",$poll,$sm_read);//вставляем в шаблон с генерированные строки

return $sm_read;//выводим результат
}

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

Поместил ее сразу после функции opros()

 

Скрипт определение имени куки

 

В самый верх файла poll.php помещаем следующий скрипт

//ОПРЕДЕЛЯЕМ ИМЯ КУКИ
$result_poll = mysql_query("SELECT id FROM poll WHERE activ = '1'");//выводим из базы данных активный опрос
$myrow_poll = mysql_fetch_array($result_poll);
$q = "quest_".$myrow_poll['id'];//опроделяем имя куки. для того что бы у каждого опроса
//была своя кука мы генерируем для каждого опроса свое имя для куки.
//вот пример имени: quest_1 или quest_2
//ОПРЕДЕЛЯЕМ ИМЯ КУКИ

Совершенно ничего сложного, простое объявление переменной q =)

 

Обработчик голосования

 

Нам осталось написать обработчик. Сложности тут никакой =)

//ОБРАБОТЧИК ПРИСВОЕНИЯ ГОЛОСА ПОЛЬЗОВАТЕЛЯ
if(isset($_POST['quePOLL'])){$quePOLL = $_POST['quePOLL'];}//определяем переменную
if(isset($quePOLL))//если переменная существует
{
$result_pollup = mysql_query("SELECT otvet FROM poll WHERE activ = '1'");//выводим ответы активного опроса
$myrow_pollup = mysql_fetch_array($result_pollup);

$otvet = explode("|",$myrow_pollup['otvet']);//делаем из строчки с ответами массив
$otvet[$quePOLL]++;//присваиваем к определенному ответу плюс один голос
//определенный ответ определяется по переменной которая была послана пользователем из формы

$otvet = implode("|",$otvet);//склеиваем ответы
$result_up_q = mysql_query ("UPDATE poll SET otvet='$otvet' WHERE activ='1'");//записываем новое значение в базу данных

//создаем куку
//определяем домен на котором будет работать создаваемая кука
preg_match("/http:\/\/(.*?)\//s",$server_root,$cookieSITE);
$cookieSITE = str_replace("www.","",$cookieSITE[1]);

setcookie($q,"YES",time()+31536000,"/",".".$cookieSITE);//создаем куку
//создаем куку

header("location: ".getenv('HTTP_REFERER'));//перенаправляем пользователя на ту страницу с которой он голосовал
exit;
}
//ОБРАБОТЧИК ПРИСВОЕНИЯ ГОЛОСА ПОЛЬЗОВАТЕЛЯ

Обработчик прибавляет голос к нужному элементу массива после чего записывает новое значение в базу данных. Так же скрипт создает куку которая будет жить ровно год. Думаю столько времени достаточно чтобы закончить опрос =)

Поместил данный код сразу после определение имени куки

 

Подключаем модуль к нашему движку

 

Теперь давайте подключим новый модуль к нашему движку. Открываем главный пользовательский файл index.php, и перед строчками

$urlsite = $server_root;
include("templates/index.html");//Подключение шаблона

Пишем вот такой скрипт

//ОПРОС
include("moduls/poll.php");//подключаем модуль опроса
if(!$_COOKIE[$q])$poll = poll(0);//если куки нет
else $poll = poll(1);//если кука есть
//ОПРОС

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

 

Вывод переменной poll в главном шаблоне нашего движка

 

Вы могли обратить внимание, что переменная в которую помещается результат работы функции poll() называется poll. Данная переменная не выводится в шаблоне index.html. Поэтому открываем наш шаблон index.html и сразу после переменной menu в правом блоке нашего блога пишем вот такой код

					<br><br>
<?=$poll?>

Таким образом весь правый блок шаблона будет выглядеть вот так:

                <!--ПРАВЫЙ БЛОК-->
<td class="border" width="210px" valign="top">
<?=$menu?>
<br><br>
<?=$poll?>
</td>
<!--ПРАВЫЙ БЛОК-->

Я думаю Вы поняли что я вывел опрос в сайтбаре нашего блога

 

вид опроса на нашем блоге

 

Заключение

 

Ну что же, теперь наш движок имеет возможность создавать для пользователей опросы =) с чем я Вас и поздравляю =) В следующих заметках мы начнем создавать мини модули для нашего движка, а именно модуль последних комментариев, читаемых постов, случайных постов категории, парсер для подсчета подписчиков RSS ленты и твиттера, навигации.

Если не хотите пропустить данные заметки, то подпишитесь на RSS ленту блога через ридер, или же по почте.

Всего Вам наилучшего! У меня на сегодня все!

Исходник

_______

P.S.: Буквально несколько недель назад открылся сезон рыбной ловли. Для любителей данного мероприятия рекомендую посетить интернет магазин рыболовных снастей. Для своего хобби, на данном ресурсе, Вы можете найти очень много всякой всячины, что поможет Вам вернуться домой с отличным уловом =)

 

Возможно Вам будут интересны следующие заметки

Комментарии (3)

Ваше имя *
Сайт
Ваш E-mail *
Ваше сообщение *
 
Санат, 07 Июня 2014 г. 22:17 пишет:
Читатель
если у меня несколько опросов, что делать? я испробовал скрипт, но он не выводит их с базы данных
Алексей, 07 Июня 2014 г. 22:41 пишет:
Автор
Я уже точно не помню, но скорее всего модуль опроса не позволяет выводить сразу несколько опросов... так что для того что бы реализовать то, что Вам нужно, придется переписать модуль...
Ответ для пользователя: Санат
Санат, 08 Июня 2014 г. 08:06 пишет:
Читатель
может поспособствуете заапдейдить этот скрипт? =)
Ответ для пользователя: Алексей