voting types now all implemented. majority and quorum removed from database
authorcommunity.cacert.org <community.cacert.org@d4452222-2f33-11de-9270-010000000000>
Sat, 30 May 2009 02:57:39 +0000 (02:57 +0000)
committercommunity.cacert.org <community.cacert.org@d4452222-2f33-11de-9270-010000000000>
Sat, 30 May 2009 02:57:39 +0000 (02:57 +0000)
git-svn-id: http://svn.cacert.cl/Software/Voting/vote@52 d4452222-2f33-11de-9270-010000000000

database.php
database.sql
motion.php
motions.php

index 30ba66a..d7b866e 100644 (file)
@@ -6,12 +6,12 @@
                function __construct() {
                        $this->dbh = new PDO("sqlite:".dirname(__FILE__)."/database.sqlite");
                        $this->statement = array();
-                       $this->statement['list decisions'] = $this->dbh->prepare("SELECT decisions.id AS id, decisions.tag AS tag, voters.name AS proposer, decisions.proposed, decisions.title, decisions.content, decisions.quorum, decisions.majority, decisions.status, decisions.due, decisions.modified, (SELECT COUNT(*) FROM votes WHERE decision=decisions.id AND vote=1) AS ayes, (SELECT COUNT(*) FROM votes WHERE decision=decisions.id AND vote=-1) AS nayes, (SELECT COUNT(*) FROM votes WHERE decision=decisions.id AND vote=0) AS abstains FROM decisions, voters WHERE decisions.proponent=voters.id ORDER BY proposed DESC LIMIT 10 OFFSET 10 * (:page - 1);");
-                       $this->statement['list my unvoted decisions'] = $this->dbh->prepare("SELECT  * FROM (SELECT decisions.id AS id, decisions.tag AS tag, voters.name AS proposer,decisions.proposed AS proposed, decisions.title AS title, decisions.content AS content, decisions.quorum AS quorum, decisions.majority AS majority, decisions.status AS status, decisions.due AS due, decisions.modified AS modified,(SELECT COUNT(*) AS ayes FROM votes WHERE decision=decisions.id AND vote=1), (SELECT COUNT(*) AS nayes FROM votes WHERE decision=decisions.id AND vote=-1), (SELECT COUNT(*) AS abstains FROM votes WHERE decision=decisions.id AND vote=0) FROM decisions, voters WHERE decisions.proponent=voters.id AND decisions.status=0) WHERE NOT EXISTS (SELECT vote FROM votes WHERE votes.decision=id AND votes.voter=:id) ORDER BY proposed DESC LIMIT 10 OFFSET 10 * (:page - 1);");
-                       $this->statement['list decision'] = $this->dbh->prepare("SELECT decisions.id AS id, decisions.tag AS tag, voters.name AS proposer, decisions.proposed, decisions.title, decisions.content, decisions.quorum, decisions.majority, decisions.status, decisions.due, decisions.modified, (SELECT COUNT(*) FROM votes WHERE decision=decisions.id AND vote=1) AS ayes, (SELECT COUNT(*) FROM votes WHERE decision=decisions.id AND vote=-1) AS nayes, (SELECT COUNT(*) FROM votes WHERE decision=decisions.id AND vote=0) AS abstains FROM decisions, voters WHERE decisions.proponent=voters.id AND decisions.tag=:id ORDER BY proposed DESC;");
-                       $this->statement['closed decisions'] = $this->dbh->prepare("SELECT decisions.id, decisions.tag, voters.name AS proposer, decisions.proposed, decisions.title, decisions.content, decisions.quorum, decisions.majority, decisions.status, decisions.due, decisions.modified, (SELECT COUNT(*) FROM votes WHERE decision=decisions.id AND vote=1) AS ayes, (SELECT COUNT(*) FROM votes WHERE decision=decisions.id AND vote=-1) AS nayes, (SELECT COUNT(*) FROM votes WHERE decision=decisions.id AND vote=0) AS abstains FROM decisions, voters WHERE decisions.proponent=voters.id AND decisions.status=0 AND datetime('now','utc') > datetime(due);");
-                       $this->statement['get decision'] = $this->dbh->prepare("SELECT decisions.id, decisions.tag, decisions.proponent, voters.name AS proposer, decisions.proposed, decisions.title, decisions.content, decisions.quorum, decisions.majority, decisions.status, decisions.due, decisions.modified, (SELECT COUNT(*) FROM votes WHERE decision=decisions.id AND vote=1) AS ayes, (SELECT COUNT(*) FROM votes WHERE decision=decisions.id AND vote=-1) AS nayes, (SELECT COUNT(*) FROM votes WHERE decision=decisions.id AND vote=0) AS abstains FROM decisions, voters WHERE decisions.proponent=voters.id AND decisions.id=:decision;");
-                       $this->statement['get new decision'] = $this->dbh->prepare("SELECT decisions.id, decisions.tag, decisions.proponent, voters.name AS proposer, decisions.proposed, decisions.title, decisions.content, decisions.quorum, decisions.majority, decisions.status, decisions.due, decisions.modified, (SELECT COUNT(*) FROM votes WHERE decision=decisions.id AND vote=1) AS ayes, (SELECT COUNT(*) FROM votes WHERE decision=decisions.id AND vote=-1) AS nayes, (SELECT COUNT(*) FROM votes WHERE decision=decisions.id AND vote=0) AS abstains FROM decisions, voters WHERE decisions.proponent=voters.id AND decisions.id=last_insert_rowid();");
+                       $this->statement['list decisions'] = $this->dbh->prepare("SELECT decisions.id AS id, decisions.tag AS tag, voters.name AS proposer, decisions.proposed, decisions.title, decisions.content, decisions.votetype, decisions.status, decisions.due, decisions.modified, (SELECT COUNT(*) FROM votes WHERE decision=decisions.id AND vote=1) AS ayes, (SELECT COUNT(*) FROM votes WHERE decision=decisions.id AND vote=-1) AS nayes, (SELECT COUNT(*) FROM votes WHERE decision=decisions.id AND vote=0) AS abstains FROM decisions, voters WHERE decisions.proponent=voters.id ORDER BY proposed DESC LIMIT 10 OFFSET 10 * (:page - 1);");
+                       $this->statement['list my unvoted decisions'] = $this->dbh->prepare("SELECT  * FROM (SELECT decisions.id AS id, decisions.tag AS tag, voters.name AS proposer,decisions.proposed AS proposed, decisions.title AS title, decisions.content AS content, decisions.votetype AS votetype, decisions.status AS status, decisions.due AS due, decisions.modified AS modified,(SELECT COUNT(*) AS ayes FROM votes WHERE decision=decisions.id AND vote=1), (SELECT COUNT(*) AS nayes FROM votes WHERE decision=decisions.id AND vote=-1), (SELECT COUNT(*) AS abstains FROM votes WHERE decision=decisions.id AND vote=0) FROM decisions, voters WHERE decisions.proponent=voters.id AND decisions.status=0) WHERE NOT EXISTS (SELECT vote FROM votes WHERE votes.decision=id AND votes.voter=:id) ORDER BY proposed DESC LIMIT 10 OFFSET 10 * (:page - 1);");
+                       $this->statement['list decision'] = $this->dbh->prepare("SELECT decisions.id AS id, decisions.tag AS tag, voters.name AS proposer, decisions.proposed, decisions.title, decisions.content, decisions.votetype, decisions.status, decisions.due, decisions.modified, (SELECT COUNT(*) FROM votes WHERE decision=decisions.id AND vote=1) AS ayes, (SELECT COUNT(*) FROM votes WHERE decision=decisions.id AND vote=-1) AS nayes, (SELECT COUNT(*) FROM votes WHERE decision=decisions.id AND vote=0) AS abstains FROM decisions, voters WHERE decisions.proponent=voters.id AND decisions.tag=:id ORDER BY proposed DESC;");
+                       $this->statement['closed decisions'] = $this->dbh->prepare("SELECT decisions.id, decisions.tag, voters.name AS proposer, decisions.proposed, decisions.title, decisions.content, decisions.votetype, decisions.status, decisions.due, decisions.modified, (SELECT COUNT(*) FROM votes WHERE decision=decisions.id AND vote=1) AS ayes, (SELECT COUNT(*) FROM votes WHERE decision=decisions.id AND vote=-1) AS nayes, (SELECT COUNT(*) FROM votes WHERE decision=decisions.id AND vote=0) AS abstains FROM decisions, voters WHERE decisions.proponent=voters.id AND decisions.status=0 AND datetime('now','utc') > datetime(due);");
+                       $this->statement['get decision'] = $this->dbh->prepare("SELECT decisions.id, decisions.tag, decisions.proponent, voters.name AS proposer, decisions.proposed, decisions.title, decisions.content, decisions.votetype, decisions.status, decisions.due, decisions.modified, (SELECT COUNT(*) FROM votes WHERE decision=decisions.id AND vote=1) AS ayes, (SELECT COUNT(*) FROM votes WHERE decision=decisions.id AND vote=-1) AS nayes, (SELECT COUNT(*) FROM votes WHERE decision=decisions.id AND vote=0) AS abstains FROM decisions, voters WHERE decisions.proponent=voters.id AND decisions.id=:decision;");
+                       $this->statement['get new decision'] = $this->dbh->prepare("SELECT decisions.id, decisions.tag, decisions.proponent, voters.name AS proposer, decisions.proposed, decisions.title, decisions.content, decisions.votetype, decisions.status, decisions.due, decisions.modified, (SELECT COUNT(*) FROM votes WHERE decision=decisions.id AND vote=1) AS ayes, (SELECT COUNT(*) FROM votes WHERE decision=decisions.id AND vote=-1) AS nayes, (SELECT COUNT(*) FROM votes WHERE decision=decisions.id AND vote=0) AS abstains FROM decisions, voters WHERE decisions.proponent=voters.id AND decisions.id=last_insert_rowid();");
                        $this->statement['get voter'] = $this->dbh->prepare("SELECT voters.id, voters.name FROM voters, emails WHERE voters.id=emails.voter AND emails.address=? AND voters.enabled=1");
                        $this->statement['get voter by id'] = $this->dbh->prepare("SELECT voters.id, voters.name FROM voters WHERE id=:id;");
                        $this->statement['get voters'] = $this->dbh->prepare("SELECT voters.id, voters.name FROM voters WHERE voters.enabled=1 ORDER BY name ASC;");
@@ -19,9 +19,9 @@
                        $this->statement['do vote'] = $this->dbh->prepare("INSERT INTO votes (decision, voter, vote, voted, notes) VALUES (:decision, :voter, :vote, datetime('now','utc'), :notes);");
                        $this->statement['stats'] = $this->dbh->prepare("SELECT COUNT(*) AS voters FROM voters WHERE enabled=1;");
                        $this->statement['list votes'] = $this->dbh->prepare("SELECT voters.name AS name, votes.vote AS vote FROM voters,votes WHERE voters.id=votes.voter AND votes.decision=:id;");
-                       $this->statement['create decision'] = $this->dbh->prepare("INSERT INTO decisions (proposed, proponent, title, content, quorum, majority, status, due, modified) VALUES (datetime('now','utc'), :proponent, :title, :content, :quorum, :majority, 0, datetime('now','utc', :due), datetime('now','utc'));");
+                       $this->statement['create decision'] = $this->dbh->prepare("INSERT INTO decisions (proposed, proponent, title, content, votetype, status, due, modified) VALUES (datetime('now','utc'), :proponent, :title, :content, :votetype, 0, datetime('now','utc', :due), datetime('now','utc'));");
                        $this->statement['post create'] = $this->dbh->prepare(" UPDATE decisions SET tag='m' || strftime('%Y%m%d','now') || '.' || id WHERE id=last_insert_rowid();");
-                       $this->statement['update decision'] = $this->dbh->prepare("UPDATE decisions SET proposed=datetime('now','utc'), proponent=:proponent, title=:title, content=:content, quorum=:quorum, majority=:majority, status=0, due=datetime('now','utc',:due), modified=datetime('now','utc') WHERE id=:id;");
+                       $this->statement['update decision'] = $this->dbh->prepare("UPDATE decisions SET proposed=datetime('now','utc'), proponent=:proponent, title=:title, content=:content, votetype=:votetype, status=0, due=datetime('now','utc',:due), modified=datetime('now','utc') WHERE id=:id;");
                        $this->statement['close decision'] = $this->dbh->prepare("UPDATE decisions SET status=:status, modified=datetime('now','utc') WHERE id=:decision");
                }
                function getStatement($name) {
                        $upd = $this->getStatement("close decision");
                        if ($stmt->execute()) {
                                while ($decision = $stmt->fetch()) {
+                                       switch ($decision['votetype']) {
+                                               case 0: // motion
+                                                       $quorum = 3; $majority = 50; break;
+                                               case 1: // veto
+                                               default:
+                                                       $quorum = 1; $majority = 99; break;
+                                       }
                                        $votes = $decision['ayes'] + $decision['nayes'] + $decision['abstains'];
-                                       if ($votes < $decision['quorum']) {
+                                       if ($votes < $quorum) {
                                                $decision['status'] = -1;
                                        } else {
                                                $votes = $decision['ayes'] + $decision['nayes'];
-                                               if (($decision['ayes'] / $votes) > ($decision['majority'] / 100)) {
+                                               if (($decision['ayes'] / $votes) > ($majority / 100)) {
                                                        $decision['status'] = 1;
                                                } else {
                                                        $decision['status'] = -1;
@@ -50,8 +57,7 @@
                                        $tag = $decision['tag'];
                                        $title = $decision['title'];
                                        $content = $decision['content'];
-                                       $quorum = $decision['quorum'];
-                                       $majority = $decision['majority'];
+                                       $votetype = !$decision['votetype']?'motion':'veto';
                                        $ayes = $decision['ayes'];
                                        $nayes = $decision['nayes'];
                                        $abstains = $decision['abstains'];
@@ -67,9 +73,7 @@ Motion:
     $title
     $content
 
-Votes:
-       Quorum: $quorum
-       Majority: $majority%
+Vote type: $votetype
        
        Ayes: $ayes
        Nayes: $nayes
index 33386c1..8fcf88d 100644 (file)
@@ -1,4 +1,4 @@
-CREATE TABLE decisions (id INTEGER PRIMARY KEY, proposed DATETIME, proponent INTEGER, title VARCHAR(255), content TEXT, quorum INTEGER, majority INTEGER, status INTEGER, due DATETIME, modified DATETIME, tag varchar(255), votetype INT4 DEFAULT 0 NOT NULL);
+CREATE TABLE decisions (id INTEGER PRIMARY KEY, proposed DATETIME, proponent INTEGER, title VARCHAR(255), content TEXT, status INTEGER, due DATETIME, modified DATETIME, tag varchar(255), votetype INT4 DEFAULT 0 NOT NULL);
 CREATE TABLE emails (voter INT4, address VARCHAR(255));
 CREATE TABLE voters (id INTEGER PRIMARY KEY, name VARCHAR(255), enabled INTEGER default 0);
 CREATE TABLE votes (decision INT4, voter INT4, vote INT4, voted DATETIME, notes text default '');
index 3559cd3..6c8b12e 100644 (file)
@@ -29,9 +29,8 @@
                                $stmt->bindParam(":proponent",$user['id']);
                                $stmt->bindParam(":title",$_POST['title']);
                                $stmt->bindParam(":content",$_POST['content']);
-                               $stmt->bindParam(":quorum",$_POST['quorum']);
-                               $stmt->bindParam(":majority",$_POST['majority']);
                                $stmt->bindParam(":due",$_POST['due']);
+                               $stmt->bindParam(":votetype",$_POST['votetype']);
                                if ($stmt->execute()) {
                                        ?>
                                        <b>The motion has been proposed!</b><br/>
@@ -45,8 +44,7 @@
                                        $title = $decision['title'];
                                        $content =$decision['content'];
                                        $due = $decision['due']." UTC";
-                                       $quorum = $decision['quorum'];
-                                       $majority = $decision['majority'];
+                                       $votetype = !$decision['votetype'] ? 'motion' : 'veto';
                                        $baseurl = "https://".$_SERVER['HTTP_HOST'].":".$_SERVER['SERVER_PORT'].preg_replace('/motion\.php/','',$_SERVER['REQUEST_URI']);
                                        $voteurl = $baseurl."vote.php?motion=".$decision['id'];
                                        $unvoted = $baseurl."motions.php?unvoted=1";
@@ -58,8 +56,7 @@ $name has modified motion $tag to the following:
 $title
 $content
 
-To pass a minimum of $quorum votes and a $majority% acceptance will be required.
-Voting will close $due.
+Vote type: $votetype
 
 To vote please choose:
 
@@ -91,8 +88,7 @@ BODY;
                                $stmt->bindParam(":proponent",$user['id']);
                                $stmt->bindParam(":title",$_POST['title']);
                                $stmt->bindParam(":content",$_POST['content']);
-                               $stmt->bindParam(":quorum",$_POST['quorum']);
-                               $stmt->bindParam(":majority",$_POST['majority']);
+                               $stmt->bindParam(":votetype",$_POST['votetype']);
                                $stmt->bindParam(":due",$_POST['due']);
                                if ($stmt->execute()) {
                                        $db->getStatement("post create")->execute();
@@ -108,8 +104,7 @@ BODY;
                                        $title = $decision['title'];
                                        $content =$decision['content'];
                                        $due = $decision['due']." UTC";
-                                       $quorum = $decision['quorum'];
-                                       $majority = $decision['majority'];
+                                       $votetype = !$decision['votetype'] ? 'motion' : 'veto';
                                        $baseurl = "https://".$_SERVER['HTTP_HOST'].":".$_SERVER['SERVER_PORT'].preg_replace('/motion\.php/','',$_SERVER['REQUEST_URI']);
                                        $voteurl = $baseurl."vote.php?motion=".$decision['id'];
                                        $unvoted = $baseurl."motions.php?unvoted=1";
@@ -121,7 +116,8 @@ $name has made the following motion:
 $title
 $content
 
-To pass a minimum of $quorum votes and a $majority% acceptance will be required.
+Vote type: $votetype
+
 Voting will close $due.
 
 To vote please choose:
@@ -155,17 +151,19 @@ BODY;
                        }
                        if (!is_numeric($motion['id'])) {
                                $motion = array();
-                               foreach (array("title","content","quorum","majority") as $column) {
+                               foreach (array("title","content") as $column) {
                                        $motion[$column] = "";
                                }
                                $motion["proposer"] = $user['name'];
+                               $motion["votetype"] = 0; // defaults to motion
                        }
                } else {
                        $motion = array();
-                       foreach (array("title","content","quorum","majority") as $column) {
+                       foreach (array("title","content") as $column) {
                                $motion[$column] = "";
                        }
                        $motion["proposer"] = $user['name'];
+                       $motion["votetype"] = 0; // defaults to motion
                }
                ?>
                <form <?php if (is_numeric($_REQUEST['motion'])) { echo(" action=\"?\""); } ?> method="POST">
@@ -178,21 +176,13 @@ BODY;
                <table>
                        <tr><td>ID:</td><td><?php echo htmlentities($motion['tag']); ?></td></tr>
                        <tr><td>Proponent:</td><td><?php echo htmlentities($motion['proposer']); ?></td></tr>
-                       <tr><td>Proposed Date/Time:</td><td><?php echo htmlentities($motion['proposed'] ? $motion['proposed']." UTC" : '(auto filled to current date/time)'); ?></td></tr>
+                       <tr><td>Proposed date/time:</td><td><?php echo htmlentities($motion['proposed'] ? $motion['proposed']." UTC" : '(auto filled to current date/time)'); ?></td></tr>
                        <tr><td>Title:</td><td><input name="title" value="<?php echo htmlentities($motion['title'])?>"></td></tr>
                        <tr><td>Text:</td><td><textarea name="content"><?php echo htmlspecialchars($motion['content'])?></textarea></td></tr>
-                       <tr><td>Quorum:</td><td><select name="quorum">
-                               <option value="<?php echo(ceil($stats["voters"])); ?>" <?php if($motion['quorum'] == $stats["voters"]) { echo(" selected=\"selected\""); } ?>>100% Votes (<?php echo($stats["voters"]); ?>)</option>
-                               <option value="<?php echo(ceil($stats["voters"] / 2)); ?>" <?php if($motion['quorum'] == ceil($stats["voters"] / 2)) { echo(" selected=\"selected\""); } ?>>50% Votes (<?php echo(ceil($stats["voters"] / 2)); ?>)</option>
-                               <option value="2" <?php if($motion['quorum'] == 2) { echo(" selected=\"selected\""); } ?>>2 Votes</option>
-                               <option value="1" <?php if($motion['quorum'] == 1) { echo(" selected=\"selected\""); } ?>>1 Vote</option>
+                       <tr><td>Vote type:</td><td><select name="votetype">
+                               <option value="0" <?php if(!$motion['votetype']) { echo(" selected=\"selected\""); } ?>>Motion</option>
+                               <option value="1" <?php if($motion['votetype']) { echo(" selected=\"selected\""); } ?>>Veto</option>
                        </select></td></tr>
-                       <tr><td>Majority:</td><td><select name="majority">
-                               <option value="50" <?php if($motion['majority'] == 50) { echo(" selected=\"selected\""); } ?>>50%</option>
-                               <option value="67" <?php if($motion['majority'] == 67) { echo(" selected=\"selected\""); } ?>>67%</option>
-                               <option value="75" <?php if($motion['majority'] == 75) { echo(" selected=\"selected\""); } ?>>75%</option>
-                               <option value="100" <?php if($motion['majority'] == 100) { echo(" selected=\"selected\""); } ?>>100%</option>
-                       </td></tr>
                        <tr><td rowspan="2">Due:</td><td><?php echo($motion['due'] ? $motion['due'].' UTC' : '(autofilled from option below)')?></td></tr>
                        <tr><td><select name="due">
                                <option value="+3 days">In 3 Days</option>
index f4ebdac..38fc34d 100644 (file)
@@ -85,14 +85,13 @@ BODY;
                                                ?>
                                                </td>
                                                <td>
-                                               <i><a href="motions.php?id=<?php echo $row['tag'].'">'.$row['tag']; ?></a></i><br/>
+                                               <i><a href="motions.php?motion=<?php echo $row['tag'].'">'.$row['tag']; ?></a></i><br/>
                                                <b><?php echo htmlentities($row['title']); ?></b><br/>
                                                <pre><?php echo htmlspecialchars($row['content']); ?></pre>
                                                <br/>
                                                <i>Due: <?php echo($row['due']); ?> UTC</i><br/>
                                                <i>Proposed: <?php echo($row['proposer']); ?> (<?php echo($row['proposed']); ?> UTC)</i><br/>
-                                               <i>Required Votes: <?php echo($row['quorum']); ?></i><br/>
-                                               <i>Majority: <?php echo($row['majority']); ?>%</i><br/>
+                                               <i>Vote type: <?php echo(!$row['votetype']?'motion':'veto'); ?></i><br/>
                                                <i>Aye|Naye|Abstain: <?php echo($row['ayes']); ?>|<?php echo($row['nayes']); ?>|<?php echo($row['abstains']); ?></i><br/>
                                        <?php
                                                if ($row['status'] ==0 || $_REQUEST['showvotes']) {