PageRenderTime 51ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/include/poll.php

https://github.com/Dratone/EveBB
PHP | 755 lines | 627 code | 102 blank | 26 comment | 232 complexity | 8ae68a7a5355ac1d67e168ab8fa5b3de MD5 | raw file
Possible License(s): GPL-2.0
  1. <?php
  2. /**
  3. * Copyright (C) 2011 Visman (visman@inbox.ru)
  4. * based on code by kg (kg@as-planned.com)
  5. * Poll Mod for FluxBB, written by As-Planned.com
  6. * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
  7. */
  8. if (!defined('PUN'))
  9. exit;
  10. if (file_exists(PUN_ROOT.'lang/'.$pun_user['language'].'/poll.php'))
  11. require PUN_ROOT.'lang/'.$pun_user['language'].'/poll.php';
  12. else
  13. require PUN_ROOT.'lang/English/poll.php';
  14. // вывод сообщений *************************************************************
  15. function poll_mess($mess, $ques = '', $vote = '')
  16. {
  17. global $lang_poll;
  18. if (empty($ques))
  19. $m = $lang_poll[$mess];
  20. else if (!empty($ques) && empty($vote))
  21. $m = sprintf($lang_poll[$mess], $ques);
  22. else
  23. $m = sprintf($lang_poll[$mess], $ques, $vote);
  24. message($lang_poll['Err poll'].'<h2>'.$m.'</h2>');
  25. }
  26. // получение данных из формы ***************************************************
  27. function poll_post($var, $default = null)
  28. {
  29. return isset($_POST[$var]) ? $_POST[$var] : $default;
  30. }
  31. // запрещено ли редактировать **************************************************
  32. function poll_noedit($tid)
  33. {
  34. global $is_admmod, $pun_config;
  35. $top = poll_topic($tid);
  36. return (!$is_admmod && ($top[0] == 2 || ($top[0] == 1 && $pun_config['o_poll_time'] != 0 && (time() - $top[1] > 60 * $pun_config['o_poll_time']))));
  37. }
  38. // доступ запрещен *************************************************************
  39. function poll_bad()
  40. {
  41. global $pun_user, $pun_config;
  42. return ($pun_user['is_guest'] || $pun_config['o_poll_enabled'] != '1');
  43. }
  44. // может ли голосовать юзер ****************************************************
  45. function poll_can_vote($tid, $uid)
  46. {
  47. global $db, $pun_user;
  48. if ($pun_user['is_guest']) return false;
  49. $result = $db->query('SELECT 1 FROM '.$db->prefix.'poll_voted WHERE tid='.$tid.' AND uid='.$uid) or error('Unable to fetch poll voted info', __FILE__, __LINE__, $db->error());
  50. return ($db->num_rows($result) == 0);
  51. }
  52. // получение информации по опросу **********************************************
  53. function poll_info($tid, $uid = NULL)
  54. {
  55. global $db;
  56. if ($tid == 0) return null;
  57. if (file_exists(FORUM_CACHE_DIR.'polls/'.$tid.'.php'))
  58. include FORUM_CACHE_DIR.'polls/'.$tid.'.php';
  59. if (!isset($kol))
  60. {
  61. $result = $db->query('SELECT question, field, choice, votes FROM '.$db->prefix.'poll WHERE tid='.$tid.' ORDER BY question, field') or error('Unable to fetch poll info', __FILE__, __LINE__, $db->error());
  62. $kol = 0;
  63. $questions = $type = $choices = $votes = array();
  64. while ($cur = $db->fetch_assoc($result))
  65. {
  66. $kol = $cur['question'];
  67. if ($cur['field'] == 0)
  68. {
  69. $questions[$kol] = $cur['choice'];
  70. $type[$kol] = $cur['votes'];
  71. $choices[$kol] = array();
  72. $votes[$kol] = array();
  73. }
  74. else
  75. {
  76. $choices[$kol][$cur['field']] = $cur['choice'];
  77. $votes[$kol][$cur['field']] = $cur['votes'];
  78. }
  79. }
  80. if ($kol == 0) return null;
  81. $rez = array(
  82. 'questions' => $questions,
  83. 'choices' => $choices,
  84. 'votes' => $votes,
  85. 'type' => $type,
  86. );
  87. if (!is_dir(FORUM_CACHE_DIR.'polls/'))
  88. mkdir(FORUM_CACHE_DIR.'polls', 0755);
  89. $fh = @fopen(FORUM_CACHE_DIR.'polls/'.$tid.'.php', 'wb');
  90. if (!$fh)
  91. error('Unable to write configuration cache file to cache(/polls) directory. Please make sure PHP has write access to this directory.', __FILE__, __LINE__);
  92. fwrite($fh, '<?php'."\n\n".'$kol = '.$kol.';'."\n\n".'$rez = '.var_export($rez, true).';'."\n\n".'?'.'>');
  93. fclose($fh);
  94. if (function_exists('apc_delete_file'))
  95. @apc_delete_file(FORUM_CACHE_DIR.'polls/'.$tid.'.php');
  96. }
  97. if ($kol == 0) return null;
  98. $rez['canVote'] = (is_null($uid)) ? false : poll_can_vote($tid, $uid);
  99. $rez['isGuest'] = (is_null($uid) || $uid > 1) ? false : true;
  100. return $rez;
  101. }
  102. // форма ввода в новой теме ****************************************************
  103. function poll_form_post($tid)
  104. {
  105. if ($tid == 0)
  106. poll_form(0);
  107. }
  108. // форма редактирования ********************************************************
  109. function poll_form_edit($tid)
  110. {
  111. poll_form($tid);
  112. }
  113. // данные по опросу ************************************************************
  114. function poll_topic($tid)
  115. {
  116. global $cur_post, $cur_topic;
  117. if ($tid == 0)
  118. {
  119. $rez = array(0,time(),0,0);
  120. }
  121. else if (isset($cur_topic['poll_type']))
  122. {
  123. $rez = array($cur_topic['poll_type'], $cur_topic['poll_time'], $cur_topic['poll_term'], $cur_topic['poll_kol']);
  124. if ($cur_topic['closed'] != '0')
  125. $rez[0] = 2;
  126. }
  127. else if (isset($cur_post['poll_type']))
  128. {
  129. $rez = array($cur_post['poll_type'], $cur_post['poll_time'], $cur_post['poll_term'], $cur_post['poll_kol']);
  130. }
  131. else
  132. $rez = array(0,time(),0,0);
  133. return $rez;
  134. }
  135. // форма ввода/редактирования **************************************************
  136. function poll_form($tid)
  137. {
  138. global $cur_index, $lang_poll, $pun_config, $tpl_main;
  139. if (poll_bad()) return;
  140. $top = poll_topic($tid);
  141. $enabled = ($top[0] > 0);
  142. $resu = ($top[2] > 1);
  143. $term = max($top[2],$pun_config['o_poll_term']);
  144. if (poll_noedit($tid))
  145. $edit = false;
  146. else
  147. $edit = true;
  148. $questions = $type = $choices = array();
  149. if ($edit && poll_post('form_sent', false))
  150. {
  151. $enabled = (poll_post('poll_enabled', 0) == 1);
  152. $resu = (poll_post('poll_result', 0) == 1);
  153. $questions = poll_post('poll_question', array());
  154. $choices = poll_post('poll_choice', array());
  155. $type = poll_post('poll_type', array());
  156. }
  157. else
  158. {
  159. $info = poll_info($tid);
  160. if (!is_null($info))
  161. {
  162. $questions = $info['questions'];
  163. $choices = $info['choices'];
  164. $type = $info['type'];
  165. }
  166. }
  167. $questions = array_map('pun_trim', $questions);
  168. $type = array_map('intval', $type);
  169. if (poll_noedit($tid))
  170. {
  171. ?>
  172. <div class="inform">
  173. <fieldset>
  174. <legend><?php echo $lang_poll['Form legend'] ?></legend>
  175. <div class="infldset txtarea">
  176. <div class="rbox"><label><input disabled="disabled" type="checkbox" id="poll_enabled" name="poll_enabled" value="1" <?php if ($enabled) echo 'checked="checked"'?> /> <?php echo $lang_poll['Form enable'] ?></label></div>
  177. <div id="poll_input">
  178. <?php
  179. if ($term > 1)
  180. {
  181. ?>
  182. <div class="rbox"><label><input disabled="disabled" type="checkbox" name="poll_result" value="1" <?php if ($resu) echo 'checked="checked"'?> /> <?php printf($lang_poll['Form result'], $term) ?></label></div>
  183. <?php
  184. }
  185. $fk = true;
  186. for ($k = 1; $k <= $pun_config['o_poll_max_ques'] && $fk; $k++)
  187. {
  188. $question = (isset($questions[$k])) ? pun_htmlspecialchars($questions[$k]) : '';
  189. if (empty($question))
  190. {
  191. $fk = false;
  192. break;
  193. }
  194. $fi = $fk;
  195. ?>
  196. <div id="poll_number_<?php echo $k ?>">
  197. <?php if ($k > 1) echo "\t\t\t\t\t\t\t<br /><hr><br />\n"; ?>
  198. <label><?php printf($lang_poll['Form question'], $k) ?><br /><input disabled="disabled" id="poll_ques_<?php echo $k ?>" class="longinput" type="text" name="poll_question[<?php echo $k ?>]" value="<?php echo $question ?>" size="80" maxlength="250" /></label>
  199. <label><?php echo $lang_poll['Form type'] ?>&nbsp;<input disabled="disabled" type="text" name="poll_type[<?php echo $k ?>]" value="<?php echo ((!isset($type[$k]) || $type[$k]<2) ? '1' : $type[$k]) ?>" size="4" maxlength="2" /></label>
  200. <?php
  201. for ($i = 1; $i <= $pun_config['o_poll_max_field'] && $fi; $i++)
  202. {
  203. $choice = (isset($choices[$k][$i])) ? pun_htmlspecialchars(pun_trim($choices[$k][$i])) : '';
  204. if (empty($choice))
  205. {
  206. $fi = false;
  207. break;
  208. }
  209. ?>
  210. <label><?php printf($lang_poll['Form choice'], $i) ?><br /><input disabled="disabled" class="longinput" type="text" name="poll_choice[<?php echo $k ?>][<?php echo $i?>]" value="<?php echo $choice ?>" size="80" maxlength="250" /></label>
  211. <?php
  212. }
  213. ?>
  214. </div>
  215. <?php
  216. }
  217. ?>
  218. </div>
  219. </div>
  220. </fieldset>
  221. </div>
  222. <?php
  223. return;
  224. }
  225. ?>
  226. <div class="inform">
  227. <fieldset>
  228. <legend><?php echo $lang_poll['Form legend'] ?></legend>
  229. <div class="infldset txtarea">
  230. <div class="rbox"><label><input type="checkbox" id="poll_enabled" name="poll_enabled" onclick="ForEnabled();" value="1" <?php if ($enabled) echo 'checked="checked"'?> tabindex="<?php echo $cur_index++ ?>" /> <?php echo $lang_poll['Form enable'] ?></label></div>
  231. <div id="poll_input">
  232. <?php
  233. if ($term > 1)
  234. {
  235. ?>
  236. <div class="rbox"><label><input type="checkbox" name="poll_result" value="1" <?php if ($resu) echo 'checked="checked"'?> tabindex="<?php echo $cur_index++ ?>" /> <?php printf($lang_poll['Form result'], $term) ?></label></div>
  237. <?php
  238. }
  239. $fk = true;
  240. for ($k = 1; $k <= $pun_config['o_poll_max_ques']; $k++)
  241. {
  242. $question = (isset($questions[$k]) && $fk) ? pun_htmlspecialchars($questions[$k]) : '';
  243. ?>
  244. <div id="poll_number_<?php echo $k ?>">
  245. <?php if ($k > 1) echo "\t\t\t\t\t\t\t<br /><hr><br />\n"; ?>
  246. <label><?php printf($lang_poll['Form question'], $k) ?><br /><input id="poll_ques_<?php echo $k ?>" class="longinput" type="text" name="poll_question[<?php echo $k ?>]" value="<?php echo $question ?>" tabindex="<?php echo $cur_index++ ?>" size="80" maxlength="250" onkeyup="ForQues(<?php echo $k ?>)" /></label>
  247. <label><?php echo $lang_poll['Form type'] ?>&nbsp;<input type="text" name="poll_type[<?php echo $k ?>]" value="<?php echo ((!isset($type[$k]) || $type[$k]<2) ? '1' : $type[$k]) ?>" tabindex="<?php echo $cur_index++ ?>" size="4" maxlength="2" /></label>
  248. <?php
  249. if (empty($question))
  250. $fk = false;
  251. $fi = $fk;
  252. for ($i = 1; $i <= $pun_config['o_poll_max_field']; $i++)
  253. {
  254. $choice = (isset($choices[$k][$i]) && $fi) ? pun_htmlspecialchars(pun_trim($choices[$k][$i])) : '';
  255. ?>
  256. <label><?php printf($lang_poll['Form choice'], $i) ?><br /><input class="longinput" type="text" name="poll_choice[<?php echo $k ?>][<?php echo $i?>]" value="<?php echo $choice ?>" tabindex="<?php echo $cur_index++ ?>" size="80" maxlength="250" onkeyup="ForChoice(<?php echo $k ?>,<?php echo $i?>)" /></label>
  257. <?php
  258. if (empty($choice))
  259. $fi = false;
  260. }
  261. ?>
  262. </div>
  263. <?php
  264. }
  265. ?>
  266. </div>
  267. </div>
  268. </fieldset>
  269. </div>
  270. <script type="text/javascript">
  271. /* <![CDATA[ */
  272. var max_ques = <?php echo $pun_config['o_poll_max_ques'] ?>;
  273. var max_field = <?php echo $pun_config['o_poll_max_field'] ?>;
  274. function ForEnabled(){var c=document.getElementById('poll_enabled');if(c.checked==true){document.getElementById('poll_input').style.display='';ForQues(1,'')}else{document.getElementById('poll_input').style.display='none'}return false}
  275. function ForChoice(num,field,t){if(num > max_ques || field > max_field){return false}var div=document.getElementById('poll_number_'+num);var i=field+1;if(typeof t != 'undefined'){if(t == 'none'){div.getElementsByTagName('label')[i].style.display='none';ForChoice(num,i,'none')}else{div.getElementsByTagName('label')[i].style.display='';ForChoice(num,field)}}else{var inp=div.getElementsByTagName('label')[i].getElementsByTagName('input')[0];if(inp.value == ""){ForChoice(num, i, 'none')}else{ForChoice(num, i, '')}}return false}
  276. function ForQues(num,t){if(num > max_ques){return false}var div=document.getElementById('poll_number_'+num);if(typeof t != 'undefined'){if(t == 'none'){div.style.display='none';ForQues(num+1,'none')}else{div.style.display='';ForQues(num)}}else{var inp=document.getElementById('poll_ques_'+num);if(inp.value == ""){div.getElementsByTagName('label')[1].style.display='none';ForChoice(num,1,'none');ForQues(num+1,'none')}else{div.getElementsByTagName('label')[1].style.display='';ForChoice(num,1,'');ForQues(num+1,'')}}return false}
  277. /* ]]> */
  278. </script>
  279. <?php
  280. $tpl_main = str_replace('<body onload="', '<body onload="ForEnabled();', $tpl_main);
  281. $tpl_main = str_replace('<body>', '<body onload="ForEnabled()">', $tpl_main);
  282. }
  283. // проверяем правильность ******************************************************
  284. function poll_form_validate($tid, &$errors)
  285. {
  286. global $lang_poll, $pun_config;
  287. if (poll_bad() || poll_noedit($tid)) return;
  288. $enabled = (poll_post('poll_enabled', 0) == 1);
  289. if ($enabled)
  290. {
  291. $questions = poll_post('poll_question', array());
  292. $choices = poll_post('poll_choice', array());
  293. $type = poll_post('poll_type', array());
  294. $questions = array_map('pun_trim', $questions);
  295. $type = array_map('intval', $type);
  296. $fk = true;
  297. $kol = 0;
  298. for ($k = 1; $k <= $pun_config['o_poll_max_ques'] && $fk; $k++)
  299. {
  300. $question = (isset($questions[$k]) && $fk) ? $questions[$k] : '';
  301. if ($question == '')
  302. $fk = false;
  303. else
  304. {
  305. $kol++;
  306. if (pun_strlen($question) > 250)
  307. $errors[] = sprintf($lang_poll['Question too long'], $k);
  308. $koc = 0;
  309. $fi = $fk;
  310. for ($i = 1; $i <= $pun_config['o_poll_max_field'] && $fi; $i++)
  311. {
  312. $choice = (isset($choices[$k][$i]) && $fi) ? pun_trim($choices[$k][$i]) : '';
  313. if ($choice == '')
  314. $fi = false;
  315. else
  316. {
  317. $koc++;
  318. if (pun_strlen($choice) > 250)
  319. $errors[] = sprintf($lang_poll['Choice too long'], $k, $i);
  320. }
  321. }
  322. if ($koc < 2)
  323. $errors[] = sprintf($lang_poll['Not enough choices'], $k);
  324. else if (!isset($type[$k]) || $type[$k] < 1 || $type[$k] >= $koc)
  325. $errors[] = sprintf($lang_poll['Max variant'], $k);
  326. }
  327. }
  328. if ($kol == 0)
  329. $errors[] = $lang_poll['No question'];
  330. }
  331. }
  332. // удаление кэша опроса ********************************************************
  333. function poll_cache_delete($tid)
  334. {
  335. if (file_exists(FORUM_CACHE_DIR.'polls/'.$tid.'.php'))
  336. @unlink(FORUM_CACHE_DIR.'polls/'.$tid.'.php');
  337. }
  338. // удаление опроса *************************************************************
  339. function poll_delete($tid, $flag = false)
  340. {
  341. global $db;
  342. $db->query('DELETE FROM '.$db->prefix.'poll WHERE tid='.$tid) or error('Unable to remove poll', __FILE__, __LINE__, $db->error());
  343. $db->query('DELETE FROM '.$db->prefix.'poll_voted WHERE tid='.$tid) or error('Unable to remove poll_voted', __FILE__, __LINE__, $db->error());
  344. if ($flag)
  345. $db->query('UPDATE '.$db->prefix.'topics SET poll_type=0, poll_time=0, poll_term=0, poll_kol=0 WHERE id='.$tid) or error('Unable to update topic', __FILE__, __LINE__, $db->error());
  346. poll_cache_delete($tid);
  347. }
  348. // сохраняем опрос *************************************************************
  349. function poll_save($tid)
  350. {
  351. global $db, $pun_config;
  352. if (poll_bad() || poll_noedit($tid)) return;
  353. $top = poll_topic($tid);
  354. $enabled = (poll_post('poll_enabled', 0) == 1);
  355. if ($enabled)
  356. {
  357. $term = 0;
  358. if (poll_post('poll_result', 0) == 1)
  359. $term = max($top[2],$pun_config['o_poll_term']);
  360. $questions = poll_post('poll_question', array());
  361. $choices = poll_post('poll_choice', array());
  362. $type = poll_post('poll_type', array());
  363. $questions = array_map('pun_trim', $questions);
  364. $type = array_map('intval', $type);
  365. $cur_ch = array();
  366. $result = $db->query('SELECT question, field FROM '.$db->prefix.'poll WHERE tid='.$tid.' ORDER BY question, field') or error('Unable to fetch poll info', __FILE__, __LINE__, $db->error());
  367. while ($ch = $db->fetch_assoc($result))
  368. $cur_ch[$ch['question']][$ch['field']] = true;
  369. $fk = true;
  370. for ($k = 1; $k <= $pun_config['o_poll_max_ques'] && $fk; $k++)
  371. {
  372. $question = (isset($questions[$k]) && $fk) ? $questions[$k] : '';
  373. if ($question == '')
  374. $fk = false;
  375. else
  376. {
  377. if (isset($cur_ch[$k][0]))
  378. {
  379. $db->query('UPDATE '.$db->prefix.'poll SET choice=\''.$db->escape($question).'\', votes='.$type[$k].' WHERE tid='.$tid.' AND question='.$k.' AND field=0') or error('Unable to update poll question', __FILE__, __LINE__, $db->error());
  380. unset($cur_ch[$k][0]);
  381. unset($cur_ch[$k][0]);
  382. }
  383. else
  384. $db->query('INSERT INTO '.$db->prefix.'poll (tid, question, field, choice, votes) VALUES ('.$tid.','.$k.',0,\''.$db->escape($question).'\','.$type[$k].')') or error('Unable to create poll question', __FILE__, __LINE__, $db->error());
  385. $fi = $fk;
  386. for ($i = 1; $i <= $pun_config['o_poll_max_field'] && $fi; $i++)
  387. {
  388. $choice = (isset($choices[$k][$i]) && $fi) ? pun_trim($choices[$k][$i]) : '';
  389. if ($choice == '')
  390. $fi = false;
  391. else
  392. {
  393. if (isset($cur_ch[$k][$i]))
  394. {
  395. $db->query('UPDATE '.$db->prefix.'poll SET choice=\''.$db->escape($choice).'\' WHERE tid='.$tid.' AND question='.$k.' AND field='.$i) or error('Unable to update poll choice', __FILE__, __LINE__, $db->error());
  396. unset($cur_ch[$k][$i]);
  397. unset($cur_ch[$k][$i]);
  398. }
  399. else
  400. $db->query('INSERT INTO '.$db->prefix.'poll (tid, question, field, choice, votes) VALUES ('.$tid.','.$k.','.$i.',\''.$db->escape($choice).'\',0)') or error('Unable to create poll choice', __FILE__, __LINE__, $db->error());
  401. }
  402. }
  403. }
  404. }
  405. $db->query('UPDATE '.$db->prefix.'topics SET poll_type=1, poll_time='.$top[1].', poll_term='.$term.', poll_kol='.$top[3].' WHERE id='.$tid) or error('Unable to update topic', __FILE__, __LINE__, $db->error());
  406. foreach($cur_ch as $k => $ch)
  407. {
  408. foreach($ch as $i => $c)
  409. {
  410. $db->query('DELETE FROM '.$db->prefix.'poll WHERE tid='.$tid.' AND question='.$k.' AND field='.$i) or error('Unable to delete poll choice', __FILE__, __LINE__, $db->error());
  411. }
  412. }
  413. poll_cache_delete($tid);
  414. }
  415. else
  416. {
  417. if ($top[0] == 0)
  418. return;
  419. poll_delete($tid, true);
  420. }
  421. }
  422. // результат голосования в теме ************************************************
  423. function poll_display_topic($tid, $uid, $p = 0)
  424. {
  425. global $pun_config;
  426. if ($pun_config['o_poll_enabled'] != '1') return;
  427. $top = poll_topic($tid);
  428. if ($top[0] == 0) return;
  429. $top[4] = $p;
  430. $info = poll_info($tid, $uid);
  431. poll_display($tid, $uid, $info, $top);
  432. }
  433. // превью в посте **************************************************************
  434. function poll_display_post($tid, $uid)
  435. {
  436. global $pun_config;
  437. if (poll_bad()) return;
  438. if ($tid > 0 && poll_noedit($tid)) // уже запрещено менять опрос
  439. {
  440. $top = poll_topic($tid);
  441. if ($top[0] == 0) return;
  442. $info = poll_info($tid, $uid);
  443. }
  444. else // а тут опрос еще можно редактировать
  445. {
  446. if (poll_post('poll_enabled', 0) != 1) return;
  447. $top = poll_topic($tid);
  448. $questions = poll_post('poll_question', array());
  449. $choices = poll_post('poll_choice', array());
  450. $type = poll_post('poll_type', array());
  451. $questions = array_map('pun_trim', $questions);
  452. $type = array_map('intval', $type);
  453. $q = $ch = array();
  454. $fk = true;
  455. for ($k = 1; $k <= $pun_config['o_poll_max_ques'] && $fk; $k++)
  456. {
  457. $question = (isset($questions[$k]) && $fk) ? $questions[$k] : '';
  458. if ($question == '')
  459. $fk = false;
  460. else
  461. {
  462. $q[$k] = $question;
  463. $ch[$k] = $votes[$k] = array();
  464. $fi = $fk;
  465. for ($i = 1; $i <= $pun_config['o_poll_max_field'] && $fi; $i++)
  466. {
  467. $choice = (isset($choices[$k][$i]) && $fi) ? pun_trim($choices[$k][$i]) : '';
  468. if ($choice == '')
  469. $fi = false;
  470. else
  471. {
  472. $ch[$k][$i] = $choice;
  473. $votes[$k][$i] = 0;
  474. }
  475. }
  476. }
  477. }
  478. $info = array(
  479. 'questions' => $q,
  480. 'choices' => $ch,
  481. 'votes' => $votes,
  482. 'type' => $type,
  483. 'isGuest' => false,
  484. );
  485. }
  486. $top[4] = 0;
  487. $info['canVote'] = true;
  488. poll_display($tid, $uid, $info, $top, true);
  489. }
  490. // отображаем результат голосования ********************************************
  491. function poll_display($tid, $uid, $info, $top, $prev = false)
  492. {
  493. global $db, $lang_poll, $pun_config, $lang_common;
  494. if (is_null($info)) return;
  495. $can_vote = ($info['canVote'] && $top[0] != 2 && poll_post('poll_view') == null);
  496. $can_visi = ((($info['isGuest'] && $pun_config['o_poll_guest'] == '1') || !$info['isGuest']) && $top[2] <= $top[3]);
  497. $fmess = '';
  498. if ($prev)
  499. $fmess = '&nbsp;';
  500. else if ($top[0] == 2)
  501. $fmess = $lang_poll['M1'];
  502. else if ($top[2] > $top[3])
  503. $fmess = sprintf($lang_poll['M2'], $top[2]);
  504. else if ($can_visi && $info['isGuest'])
  505. $fmess = $lang_poll['M3'];
  506. else if ($info['isGuest'])
  507. $fmess = $lang_poll['M4'];
  508. else if (poll_post('poll_view') != null)
  509. $fmess = '<a href="javascript:history.go(-1)">'.$lang_common['Go back'].'</a>';
  510. else if (!$can_vote)
  511. $fmess = $lang_poll['M0'];
  512. $questions = $info['questions'];
  513. $choices = $info['choices'];
  514. $types = $info['type'];
  515. $votes = $info['votes'];
  516. if ($can_vote && !$prev)
  517. {
  518. ?>
  519. <div id="poll_form">
  520. <form method="post" action="viewtopic.php?id=<?php echo $tid.($top[4] > 1 ? '&amp;p='.$top[4] : '') ?>">
  521. <?php
  522. }
  523. $amax = array();
  524. foreach($questions as $k => $question)
  525. {
  526. $choice = $choices[$k];
  527. $vote = $votes[$k];
  528. $amax[$k] = count($choice);
  529. $max = 0;
  530. foreach ($vote as $v)
  531. {
  532. if ($v > $max) $max = $v;
  533. }
  534. $maxPercent = ($top[3] == 0 || !$max) ? 1 : 100 * $max / $top[3];
  535. ?>
  536. <?php if ($can_vote && !$prev): ?>
  537. <input type="hidden" name="poll_max[<?php echo $k ?>]" value="<?php echo $amax[$k] ?>" />
  538. <?php endif ?>
  539. <fieldset class="poll">
  540. <p><?php echo pun_htmlspecialchars($question) ?></p>
  541. <?php if ($can_vote && $types[$k]>1): ?>
  542. <div class="poss"><?php printf($lang_poll['Possible choose'], $types[$k]) ?></div>
  543. <?php endif ?>
  544. <ol>
  545. <?php
  546. foreach ($choice as $i => $ch)
  547. {
  548. if (empty($ch)) continue;
  549. $percent = ($top[3] == 0) ? 0 : round(100 * $vote[$i] / $top[3],2);
  550. ?>
  551. <li>
  552. <?php
  553. if ($can_vote)
  554. {
  555. if ($types[$k] < 2)
  556. echo "\t\t\t\t\t".'<label><input type="radio" name="poll_vote['.$k.'][0]" value="'.$i.'" /> '.pun_htmlspecialchars($ch).'</label>';
  557. else
  558. echo "\t\t\t\t\t".'<label><input type="checkbox" name="poll_vote['.$k.']['.$i.']" value="1" /> '.pun_htmlspecialchars($ch).'</label>';
  559. }
  560. else if ($can_visi)
  561. {
  562. echo "\t\t\t\t\t".'<span class="answer">'.pun_htmlspecialchars($ch).'</span><span class="percent">('.$lang_poll['Votes'].$vote[$i].' ['.$percent.'%])</span>';
  563. echo '<p class="progressbar"><span style="width: '.round(100 * $percent / $maxPercent).'%;"><span>'.$percent.'%</span></span> </p>';
  564. }
  565. else
  566. {
  567. echo "\t\t\t\t\t".'<span class="answer">'.pun_htmlspecialchars($ch).'</span>';
  568. }
  569. ?>
  570. </li>
  571. <?php
  572. }
  573. ?>
  574. </ol>
  575. <div class="total"><?php printf($lang_poll['Vote total'], $top[3]) ?></div>
  576. </fieldset>
  577. <?php
  578. }
  579. if ($can_vote && !$prev)
  580. {
  581. $csrf = pun_hash($tid.(pun_hash($uid.count($questions).implode('0',$types))).get_remote_address().implode('.',$amax));
  582. foreach ($types as $i => $type)
  583. {
  584. ?>
  585. <input type="hidden" name="poll_type[<?php echo $i ?>]" value="<?php echo $type ?>" />
  586. <?php
  587. }
  588. ?>
  589. <input type="hidden" name="poll_ques" value="<?php echo count($questions) ?>" />
  590. <input type="hidden" name="poll_csrf" value="<?php echo $csrf ?>" />
  591. <p class="pollbut"><input type="submit" name="poll_submit" value="<?php echo $lang_poll['Vote button'] ?>" /><?php echo (($can_visi && $top[3] > 0) ? '<input type="submit" name="poll_view" value="'.$lang_poll['View'].'" />' : '') ?></p>
  592. </form>
  593. </div>
  594. <?php
  595. }
  596. else if (!empty($fmess))
  597. echo "\t".'<p class="poll_mess">'.$fmess.'</p>'."\n";
  598. }
  599. // голосуем ********************************************************************
  600. function poll_vote($tid, $uid)
  601. {
  602. global $db;
  603. if (poll_bad() || !poll_can_vote($tid, $uid)) poll_mess('Err1');
  604. $csrf = poll_post('poll_csrf');
  605. $ques = poll_post('poll_ques');
  606. $type = poll_post('poll_type');
  607. $votes = poll_post('poll_vote');
  608. $amax = poll_post('poll_max');
  609. if (is_null($csrf) || is_null($ques) || is_null($type) || is_null($votes) || is_null($amax)) poll_mess('Err2');
  610. if (!is_array($type) || !is_array($votes) || !is_array($amax)) poll_mess('Err2');
  611. $type = array_map('intval', $type);
  612. $amax = array_map('intval', $amax);
  613. $ques = intval($ques);
  614. $csrf2 = pun_hash($tid.(pun_hash($uid.$ques.implode('0',$type))).get_remote_address().implode('.',$amax));
  615. if ($csrf2 != $csrf) poll_mess('Err2');
  616. $kol = 0;
  617. foreach($votes as $k => $vote)
  618. {
  619. if ($k < 1 || $k > $ques) poll_mess('Err3');
  620. $kol++;
  621. $kk = 0;
  622. $vote = array_map('intval', $vote);
  623. foreach($vote as $i => $vo)
  624. {
  625. if ($type[$k] < 2 && $i != 0) poll_mess('Err2');
  626. if ($type[$k] < 2 && $vo < 1) poll_mess('Err2');
  627. if ($type[$k] < 2 && $vo > $amax[$k]) poll_mess('Err2');
  628. if ($type[$k] > 1 && $i == 0) poll_mess('Err2');
  629. if ($type[$k] > 1 && $i > $amax[$k]) poll_mess('Err2');
  630. if ($type[$k] > 1 && $vo != 1) poll_mess('Err2');
  631. $kk++;
  632. }
  633. if ($type[$k] < 2 && $kk != 1) poll_mess('Err4', $k);
  634. if ($type[$k] > 1 && ($kk < 1 || $kk > $type[$k])) poll_mess('Err5', $k, $type[$k]);
  635. }
  636. if ($kol != $ques) poll_mess('Err6');
  637. $arr = array();
  638. foreach($votes as $k => $vote)
  639. {
  640. $vote = array_map('intval', $vote);
  641. foreach($vote as $i => $vo)
  642. {
  643. if ($type[$k] < 2) $j = $vo;
  644. else $j = $i;
  645. $arr[] = '(question='.$k.' AND field='.$j.')';
  646. }
  647. }
  648. if (!empty($arr))
  649. $db->query('UPDATE '.$db->prefix.'poll SET votes=votes+1 WHERE tid='.$tid.' AND ('.implode(' OR ', $arr).')') or error('Unable to update poll choice', __FILE__, __LINE__, $db->error());
  650. $db->query('INSERT INTO '.$db->prefix.'poll_voted (tid, uid, rez) VALUES ('.$tid.','.$uid.',\''.$db->escape(serialize($votes)).'\')') or error('Unable to save vote', __FILE__, __LINE__, $db->error());
  651. $db->query('UPDATE '.$db->prefix.'topics SET poll_kol=poll_kol+1 WHERE id='.$tid) or error('Unable to update topic', __FILE__, __LINE__, $db->error());
  652. poll_cache_delete($tid);
  653. }