您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

voting.php 7.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. <?php
  2. include('../inc/inc.php');
  3. if (!$user->loggedin()) {
  4. header('Location: /login.php');
  5. die();
  6. }
  7. if ($user->getRole() !== "admin") {
  8. header('Location: /index.php');
  9. die();
  10. }
  11. function loadPositions() {
  12. global $db;
  13. $_pos = $db->fetchAssoc("select position as code, description as label, active from positions");
  14. $positions = [];
  15. foreach ($_pos as $position)
  16. $positions[$position['code']] = [ "label" => $position['label'], "active" => $position['active']];
  17. return $positions;
  18. }
  19. function loadVoters() {
  20. global $db;
  21. return $db->fetchAssoc('
  22. select
  23. MIN(skymanager_id) as `skymanager_id`,
  24. MIN(members.voting_id) as `voting_id`,
  25. MIN(name) as `name`,
  26. MIN(username) as `username`,
  27. group_concat(proxy.voting_id) as `proxies`,
  28. MIN(upstream_proxy.delegate_id) as `delegate`,
  29. md5(coalesce(MIN(email), "")) as `gravatar_hash`
  30. from members
  31. left join proxy on (members.voting_id=proxy.delegate_id)
  32. left join proxy as upstream_proxy on (upstream_proxy.voting_id=members.voting_id)
  33. where members.voting_id is not null
  34. group by members.voting_id
  35. UNION
  36. select skymanager_id, voting_id, name, username, NULL as `proxies`, NULL as `delegate`, md5(coalesce(email, "")) as `gravatar_hash`
  37. from members where members.voting_id is null');
  38. }
  39. $result = null;
  40. // Create Position
  41. if (!empty($_POST['create'])) {
  42. $code = $_POST['add-position'];
  43. $desc = $_POST['add-description'];
  44. if (empty($code) || empty($desc)) $error = "Both code and description are required";
  45. if (empty($error)) {
  46. $result = $db->query('INSERT INTO positions (position, description) VALUES ("' . $db->sanitize($code) . '", "' . $db->sanitize($desc) . '")');
  47. if ($result === false)
  48. $error = "That position already exists.";
  49. else
  50. $error = "Created position " . htmlspecialchars($desc);
  51. }
  52. } else if (!empty($_POST['setActive']) || !empty($_POST['deactivate'])) {
  53. $positions = loadPositions();
  54. $position = $_POST['ballot'];
  55. if (!array_key_exists($position, $positions)) $error = "That position does not exist";
  56. if (!empty($_POST['deactivate']))
  57. $position='';
  58. if (empty($error)) {
  59. $result = $db->query('UPDATE positions set active=(position="' . $db->sanitize($_POST['ballot']) . '")');
  60. if ($result === false)
  61. $error = "Failed to set active position";
  62. else if (empty($position))
  63. $error = "Deactivated voting form";
  64. else
  65. $error = "Set " . htmlspecialchars($positions[$_POST['ballot']]['label']) . " as active.";
  66. }
  67. } else if (!empty($_POST['remove'])) {
  68. $positions = loadPositions();
  69. if (!array_key_exists($_POST['ballot'], $positions)) $error = "That position does not exist";
  70. if (empty($error)) {
  71. $result = $db->query('DELETE FROM positions WHERE position="' . $db->sanitize($_POST['ballot']) . '"');
  72. if ($result === false)
  73. $error = "Failed to remove position";
  74. else
  75. $error = "Removed " . htmlspecialchars($positions[$_POST['ballot']]['label']) . " and discarded cast ballots.";
  76. }
  77. } else if (!empty($_POST['force'])) {
  78. $voters = loadVoters();
  79. $values = [];
  80. $vid = [];
  81. foreach ($voters as $voter) {
  82. $vid[$voter['skymanager_id']] = $voter;
  83. if ($voter['voting_id'])
  84. array_push($values, $voter['voting_id']);
  85. }
  86. if (!array_key_exists($_POST['voter-smid'], $vid))
  87. $error = "Voter does not exist";
  88. sort($values);
  89. $count = count($values);
  90. $rand = rand(100, 999-$count);
  91. for ($i = 0; $i < $count && $values[$i] <= $rand; $i++) {
  92. $rand++;
  93. }
  94. if (empty($error)) {
  95. $result = $db->query('UPDATE members set voting_id=' . ((int) $rand) . ' where skymanager_id=' . ((int) $_POST['voter-smid']));
  96. if ($result === false)
  97. $error = "Failed to force check-in. Please try again.";
  98. else
  99. $error = "Assigned voting id $rand to {$vid[$_POST['voter-smid']]['name']}";
  100. }
  101. }
  102. $positions = loadPositions();
  103. $voters = loadVoters();
  104. $header = new Header("Michigan Flyers Election : Admin");
  105. $header->addStyle("/styles/style.css");
  106. $header->addStyle("/styles/admin.css");
  107. $header->addStyle("/styles/vote.css");
  108. $header->addScript("/js/jquery-1.11.3.min.js");
  109. $header->addScript("/js/search.js");
  110. $header->addScript("/js/admin-search.js");
  111. $header->setAttribute('title', 'Michigan Flyers');
  112. $header->setAttribute('tagline', 'Election Administration Tools');
  113. $header->output();
  114. ?>
  115. <script type="text/javascript">
  116. var voters = <?= json_encode($voters); ?>;
  117. </script>
  118. <form action="voting.php" method="POST">
  119. <!--
  120. <div class="form-row">
  121. <div class="selector">
  122. <label class="radio">
  123. <input type="radio" name="button" value="ci" />
  124. <a class="radio-button-label" href="/admin/checkin.php">Check-In</a>
  125. </label>
  126. <label class="radio">
  127. <input type="radio" name="button" value="pe" />
  128. <a class="radio-button-label" href="/admin/paper.php">Paper Entry</a>
  129. </label>
  130. <label class="radio">
  131. <input type="radio" name="button" value="vo" checked />
  132. <a class="radio-button-label" href="#">Voting</a>
  133. </label>
  134. <label class="radio">
  135. <input type="radio" name="button" value="re" />
  136. <a class="radio-button-label" href="/admin/results.php">Results</a>
  137. </label>
  138. </div>
  139. </div>
  140. -->
  141. <?php if (!empty($error) || !empty($result)): ?>
  142. <div id="vote-result">
  143. <div id="status" class="<?= $result ? "success" : "failure"; ?>"></div>
  144. <div id="message" class="<?= $result ? "success" : "failure"; ?>">
  145. <?= !empty($error) ? $error : ($result ? "This Ballot has been successfully Submitted" :
  146. "This ballot has already been submitted.") ?>
  147. </div>
  148. </div>
  149. <?php endif; ?>
  150. <?php if (!empty($positions)): ?>
  151. <div class="form-section">
  152. <h3>Manage Positions</h3>
  153. <div class="form-row">
  154. <div class="selector">
  155. <?php foreach ($positions as $code => $position): ?>
  156. <label class="radio">
  157. <input type="radio" id="vote-<?= $code ?>" name="ballot" value="<?= $code ?>" <?= ($position['active']) ? 'checked' : '' ?> />
  158. <span class="radio-button-label"><?= $position['label'] ?></span>
  159. </label>
  160. <?php endforeach; ?>
  161. </div>
  162. </div>
  163. <div class="form-row split-button">
  164. <input class="submit danger" type="submit" name="remove" value="Remove Position & Ballots" />
  165. <input class="submit" type="submit" name="deactivate" value="Deactivate" />
  166. <input class="submit" type="submit" name="setActive" value="Set Active" />
  167. </div>
  168. </div>
  169. <?php endif; ?>
  170. <div class="form-section">
  171. <h3>Add Position</h3>
  172. <div class="form-row">
  173. <label for="add-position">Add Position Code</label>
  174. <input type="text" placeholder="PRES" id="add-position" name="add-position" value="" />
  175. </div>
  176. <div class="form-row">
  177. <label for="add-description">Add Position Description</label>
  178. <input type="text" placeholder="President" id="add-description" name="add-description" value="" />
  179. </div>
  180. <div class="form-row">
  181. <input class="submit" type="submit" name="create" value="Create Position" />
  182. </div>
  183. </div>
  184. <div class="form-section">
  185. <h3>Force Check-In</h3>
  186. <div class="form-row">
  187. <input type="text" placeholder="Voter Search" id="voter-searchbox" name="voter-searchbox" value="" />
  188. <div id="voter-results"></div>
  189. <input type="hidden" name="voter" id="voter-input" value="0" />
  190. <input type="hidden" name="voter-smid" id="voter-smid" value="0" />
  191. <div id="selectedVoter" class="selected candidate voter">
  192. <span class="placeholder">No Selected Voter</span>
  193. </div>
  194. </div>
  195. <div class="form-row">
  196. <input class="submit" type="submit" name="force" value="Force Check In" />
  197. </div>
  198. </div>
  199. </form>
  200. <?php
  201. $footer = new Footer();
  202. $footer->output();