PageRenderTime 24ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/concrete/blocks/survey/controller.php

https://gitlab.com/koodersmiikka/operaatio-terveys
PHP | 315 lines | 261 code | 42 blank | 12 comment | 23 complexity | cd09dc05903002eb216acd37d1e1e718 MD5 | raw file
  1. <?php
  2. namespace Concrete\Block\Survey;
  3. use Concrete\Core\Block\BlockController;
  4. use Page;
  5. use User;
  6. use Core;
  7. use Database;
  8. class Controller extends BlockController
  9. {
  10. public $options = array();
  11. protected $btTable = 'btSurvey';
  12. protected $btInterfaceWidth = "420";
  13. protected $btInterfaceHeight = "400";
  14. protected $btExportTables = array('btSurvey', 'btSurveyOptions', 'btSurveyResults');
  15. public function on_start()
  16. {
  17. $this->cID = null;
  18. $c = Page::getCurrentPage();
  19. if (is_object($c)) {
  20. $this->cID = $c->getCollectionID();
  21. }
  22. if ($this->bID) {
  23. $db = Database::connection();
  24. $v = array($this->bID);
  25. $q = "SELECT optionID, optionName, displayOrder FROM btSurveyOptions WHERE bID = ? ORDER BY displayOrder ASC";
  26. $r = $db->query($q, $v);
  27. $this->options = array();
  28. if ($r) {
  29. while ($row = $r->fetchRow()) {
  30. $opt = new Option();
  31. $opt->optionID = $row['optionID'];
  32. $opt->cID = $this->cID;
  33. $opt->optionName = $row['optionName'];
  34. $opt->displayOrder = $row['displayOrder'];
  35. $this->options[] = $opt;
  36. }
  37. }
  38. }
  39. }
  40. /**
  41. * Used for localization. If we want to localize the name/description we have to include this.
  42. */
  43. public function getBlockTypeDescription()
  44. {
  45. return t("Provide a simple survey, along with results in a pie chart format.");
  46. }
  47. public function getBlockTypeName()
  48. {
  49. return t("Survey");
  50. }
  51. public function getQuestion()
  52. {
  53. return $this->question;
  54. }
  55. public function getPollOptions()
  56. {
  57. return $this->options;
  58. }
  59. public function delete()
  60. {
  61. $db = Database::connection();
  62. $v = array($this->bID);
  63. $q = "DELETE FROM btSurveyOptions WHERE bID = ?";
  64. $db->query($q, $v);
  65. $q = "DELETE FROM btSurveyResults WHERE bID = ?";
  66. $db->query($q, $v);
  67. parent::delete();
  68. }
  69. public function action_form_save_vote($bID = false)
  70. {
  71. if ($this->bID != $bID) {
  72. return false;
  73. }
  74. $u = new User();
  75. $db = Database::connection();
  76. $bo = $this->getBlockObject();
  77. if ($this->post('rcID')) {
  78. // we pass the rcID through the form so we can deal with stacks
  79. $c = Page::getByID($this->post('rcID'));
  80. } else {
  81. $c = $this->getCollectionObject();
  82. }
  83. if ($this->requiresRegistration()) {
  84. if (!$u->isRegistered()) {
  85. $this->redirect('/login');
  86. }
  87. }
  88. if (!$this->hasVoted()) {
  89. $antispam = Core::make('helper/validation/antispam');
  90. if ($antispam->check('', 'survey_block')) { // we do a blank check which will still check IP and UserAgent's
  91. $duID = 0;
  92. if ($u->getUserID() > 0) {
  93. $duID = $u->getUserID();
  94. }
  95. /** @var \Concrete\Core\Permission\IPService $iph */
  96. $iph = Core::make('helper/validation/ip');
  97. $ip = $iph->getRequestIP();
  98. $ip = ($ip === false) ? ('') : ($ip->getIp($ip::FORMAT_IP_STRING));
  99. $v = array(
  100. $_REQUEST['optionID'],
  101. $this->bID,
  102. $duID,
  103. $ip,
  104. $this->cID, );
  105. $q = "INSERT INTO btSurveyResults (optionID, bID, uID, ipAddress, cID) VALUES (?, ?, ?, ?, ?)";
  106. $db->query($q, $v);
  107. setcookie("ccmPoll" . $this->bID . '-' . $this->cID, "voted", time() + 1296000, DIR_REL . '/');
  108. $this->redirect($c->getCollectionPath() . '?survey_voted=1');
  109. }
  110. }
  111. }
  112. public function requiresRegistration()
  113. {
  114. return $this->requiresRegistration;
  115. }
  116. public function hasVoted()
  117. {
  118. $u = new User();
  119. if ($u->isRegistered()) {
  120. $db = Database::connection();
  121. $v = array($u->getUserID(), $this->bID, $this->cID);
  122. $q = "SELECT count(resultID) AS total FROM btSurveyResults WHERE uID = ? AND bID = ? AND cID = ?";
  123. $result = $db->getOne($q, $v);
  124. if ($result > 0) {
  125. return true;
  126. }
  127. } elseif ($_COOKIE['ccmPoll' . $this->bID . '-' . $this->cID] == 'voted') {
  128. return true;
  129. }
  130. return false;
  131. }
  132. public function duplicate($newBID)
  133. {
  134. $db = Database::connection();
  135. foreach ($this->options as $opt) {
  136. $v1 = array($newBID, $opt->getOptionName(), $opt->getOptionDisplayOrder());
  137. $q1 = "INSERT INTO btSurveyOptions (bID, optionName, displayOrder) VALUES (?, ?, ?)";
  138. $db->query($q1, $v1);
  139. $v2 = array($opt->getOptionID());
  140. $newOptionID = $db->Insert_ID();
  141. $q2 = "SELECT * FROM btSurveyResults WHERE optionID = ?";
  142. $r2 = $db->query($q2, $v2);
  143. if ($r2) {
  144. while ($row = $r2->fetchRow()) {
  145. $v3 = array($newOptionID, $row['uID'], $row['ipAddress'], $row['timestamp']);
  146. $q3 = "INSERT INTO btSurveyResults (optionID, uID, ipAddress, timestamp) VALUES (?, ?, ?, ?)";
  147. $db->query($q3, $v3);
  148. }
  149. }
  150. }
  151. return parent::duplicate($newBID);
  152. }
  153. public function save($args)
  154. {
  155. parent::save($args);
  156. $db = Database::connection();
  157. if (!is_array($args['survivingOptionNames'])) {
  158. $args['survivingOptionNames'] = array();
  159. }
  160. $slashedArgs = array();
  161. foreach ($args['survivingOptionNames'] as $arg) {
  162. $slashedArgs[] = addslashes($arg);
  163. }
  164. $db->query(
  165. "DELETE FROM btSurveyOptions WHERE optionName NOT IN ('" . implode(
  166. "','",
  167. $slashedArgs) . "') AND bID = " . intval($this->bID));
  168. if (is_array($args['pollOption'])) {
  169. $displayOrder = 0;
  170. foreach ($args['pollOption'] as $optionName) {
  171. $v1 = array($this->bID, $optionName, $displayOrder);
  172. $q1 = "INSERT INTO btSurveyOptions (bID, optionName, displayOrder) VALUES (?, ?, ?)";
  173. $db->query($q1, $v1);
  174. ++$displayOrder;
  175. }
  176. }
  177. $query = "DELETE FROM btSurveyResults
  178. WHERE optionID NOT IN (
  179. SELECT optionID FROM btSurveyOptions WHERE bID = {$this->bID}
  180. )
  181. AND bID = {$this->bID} ";
  182. $db->query($query);
  183. }
  184. public function displayChart($bID, $cID)
  185. {
  186. // Prepare the database query
  187. $db = Database::connection();
  188. // Get all available options
  189. $options = array();
  190. $v = array(intval($bID));
  191. $q = 'SELECT optionID, optionName FROM btSurveyOptions WHERE bID = ? ORDER BY displayOrder ASC';
  192. $r = $db->Execute($q, $v);
  193. $i = 0;
  194. while ($row = $r->fetchRow()) {
  195. $options[$i]['name'] = $row['optionName'];
  196. $options[$i]['id'] = $row['optionID'];
  197. ++$i;
  198. }
  199. // Get chosen count for each option
  200. $total_results = 0;
  201. $i = 0;
  202. foreach ($options as $option) {
  203. $v = array($option['id'], intval($bID), intval($cID));
  204. $q = 'SELECT count(*) FROM btSurveyResults WHERE optionID = ? AND bID = ? AND cID = ?';
  205. $r = $db->Execute($q, $v);
  206. if ($row = $r->fetchRow()) {
  207. $options[$i]['amount'] = $row['count(*)'];
  208. $total_results += $row['count(*)'];
  209. }
  210. ++$i;
  211. }
  212. if ($total_results <= 0) {
  213. $chart_options = '<div style="text-align: center; margin-top: 15px;">' . t(
  214. 'No data is available yet.') . '</div>';
  215. $this->set('chart_options', $chart_options);
  216. return;
  217. }
  218. // Convert option counts to percentages, initiate colors
  219. $availableChartColors = array(
  220. '00CCdd',
  221. 'cc3333',
  222. '330099',
  223. 'FF6600',
  224. '9966FF',
  225. 'dd7700',
  226. '66DD00',
  227. '6699FF',
  228. 'FFFF33',
  229. 'FFCC33',
  230. '00CCdd',
  231. 'cc3333',
  232. '330099',
  233. 'FF6600',
  234. '9966FF',
  235. 'dd7700',
  236. '66DD00',
  237. '6699FF',
  238. 'FFFF33',
  239. 'FFCC33',
  240. );
  241. $percentage_value_string = '';
  242. foreach ($options as $option) {
  243. $option['amount'] /= $total_results;
  244. $percentage_value_string .= round($option['amount'], 3) . ',';
  245. $graphColors[] = array_pop($availableChartColors);
  246. }
  247. // Strip off trailing comma
  248. $percentage_value_string = substr_replace($percentage_value_string, '', -1);
  249. // Get Google Charts API image
  250. $img_src = '<img class="surveyChart" style="margin-bottom:10px;" border="" src="//chart.apis.google.com/chart?cht=p&chd=t:' . $percentage_value_string . '&chs=180x180&chco=' . implode(
  251. ',',
  252. $graphColors) . '" />';
  253. $this->set('pie_chart', $img_src);
  254. // Build human-readable option list
  255. $i = 1;
  256. $chart_options = '<table class="table"><tbody>';
  257. foreach ($options as $option) {
  258. $chart_options .= '<tr>';
  259. $chart_options .= '<td>';
  260. $chart_options .= '<strong>' . trim($options[$i - 1]['name']) . '</strong>';
  261. $chart_options .= '</td>';
  262. $chart_options .= '<td style="text-align:right; white-space: nowrap">';
  263. $chart_options .= ($option['amount'] > 0) ? round($option['amount'] / $total_results * 100) : 0;
  264. $chart_options .= '%';
  265. $chart_options .= '<div class="surveySwatch" style="border-radius: 3px; margin-left: 6px; width:18px; height:18px; float:right; background:#' . $graphColors[$i - 1] . '"></div>';
  266. $chart_options .= '</td>';
  267. $chart_options .= '</tr>';
  268. ++$i;
  269. }
  270. $chart_options .= '</tbody></table>';
  271. $this->set('chart_options', $chart_options);
  272. }
  273. }