. */ require_once(FILESYSTEMROOTPATH."include/classes/IDao.php"); require_once(FILESYSTEMROOTPATH."jc/include/model/RankedVote.php"); class RankedVoteDao implements IDao { /** MySQL object */ private $mysql; /** * Default constructor */ public function __construct(MySQL $mysql) { $this->mysql = $mysql; } /** * Load Polls by id * * @param id * @return */ public function load($id) { $query = "SELECT * FROM `rankedVote` WHERE `id`='".$id."'"; if( $this->mysql->query($query) ) { return new RankedVote($this->mysql->fetchArray()); }else { return array(); } } public function loadByAgora($agora_id) { $query = 'SELECT * FROM `rankedVote` WHERE `agora_id`="'.$agora_id.'"'; if( $this->mysql->query($query) ) { $ret = array(); while( $row = $this->mysql->fetchArray() ) { $row['edit'] = 'Edit'; if (date("Y-m-d H:i:s") > $row['close']){ $row['results'] = 'Results';; } else{ $row['results'] = '-'; } $row['percentage'] = 0; $row['rankedOptions'] = 'Options'; $ret[$row['id']] = $row; } foreach ($ret as $id => $row){ $already_cast = $this->rvballots_cast($id); $votes_available = $this->rvballots_to_be_cast(); if ($votes_available != 0){ $percentage = sprintf("%.2f",100*$already_cast/$votes_available); }else{ $percentage = '0.00'; } $ret[$id]['percentage']=$percentage; } return $ret; }else { return array(); } } public function rvballots_to_be_cast(){ $aid = $_SESSION['JC_MODULE']['AgoraId']; $query = 'SELECT SUM(numberOfVotes) AS to_be_cast FROM `voting_numberofvotes` WHERE agora_id='.$aid.' AND BodyCode IN (SELECT DISTINCT bodyCode FROM `voting_delegates` WHERE `registered`=1 AND `departed`=0 AND `status`="delegate" AND `agora_id`='.$aid.')'; if( $this->mysql->query($query) ) { $result = $this->mysql->fetchArray(); }else { return ''; } return $result['to_be_cast']; } public function rvballots_cast($id){ $aid = $_SESSION['JC_MODULE']['AgoraId']; $query = 'SELECT COUNT(DISTINCT `ticket`) AS total_tickets FROM `rankedVoteBallots` WHERE rankedVote_id='.$id; if( $this->mysql->query($query) ) { $result = $this->mysql->fetchArray(); }else { return ''; } return $result['total_tickets']; } public function loadOpen($agora_id){ $query = 'SELECT *,closemysql->query($query) ) { $ret = array(); while( $row = $this->mysql->fetchArray() ) { $row['rankedVoteOptions'] = 'Options'; $row['vote'] = 'Vote'; $row['check'] = 'Check'; if($row['hasClosed']==0){ $row['vote']=''.$row['vote'].''; $row['title'] = ''.$row['title'].''; } $ret[$row['id']] = $row; } return $ret; }else { return array(); } } public function countVotes($id) { $aid = $_SESSION['JC_MODULE']['AgoraId']; $query = 'UPDATE `rankedVote` SET `bodies_available`=(SELECT count(DISTINCT `bodyCode`) FROM `voting_delegates` WHERE `registered`=1 AND `agora_id`='.$aid.') WHERE `id`='.$id; if( !$this->mysql->query($query) ) { return ''; } $query = 'UPDATE `rankedVote` SET `bodies_voted`= (SELECT count(DISTINCT `bodyCode`) FROM `rankedVoteBallots` WHERE `rankedVote_id`='.$id.') WHERE `id`='.$id; $results=array(); if( !$this->mysql->query($query) ) { return ''; } $query = 'UPDATE `rankedVote` SET `votes_available`=(SELECT SUM(`numberOfVotes`) FROM `voting_numberofvotes` WHERE `agora_id`='.$aid.' AND `BodyCode` IN (SELECT DISTINCT `bodyCode` FROM `voting_delegates` WHERE `registered`=1 AND `departed`=0 AND `status`="delegate" AND agora_id='.$aid.')) WHERE `id`='.$id; if( !$this->mysql->query($query) ) { return ''; } $query = 'UPDATE `rankedVote` SET `votes_cast`=(SELECT COUNT(DISTINCT `ticket`) FROM `rankedVoteBallots` WHERE `rankedVote_id`='.$id.') WHERE `id`='.$id; if( !$this->mysql->query($query) ) { return ''; } //schultze method //see wikipedia for implmentation $query = "SELECT `id` FROM `rankedVoteOptions` WHERE `rankedVote_id`=$id ORDER BY `id`"; if( $this->mysql->query($query) ) { $candidates = array(); $k = 0; while( $row = $this->mysql->fetchArray() ) { $candidates[$row["id"]]= $k; $candidates_id[$k]= $row["id"]; $k = $k + 1; } } $C = count($candidates); /* $query = "SELECT COUNT(DISTINCT `ticket`) AS `B` FROM `rankedVoteBallots` WHERE `rankedVote_id`=$id"; $this->mysql->query($query); $row = $this->mysql->fetchArray(); $B = $row["B"]; echo "B=".$B; */ //create $votes: matrix BallotsxCandidates BxC //$votes = array_fill(0, $B, array_fill(0, $C, 0)); $query = "SELECT * FROM `rankedVoteBallots` WHERE `rankedVote_id`=$id AND `rankedVoteOption_id`<>-1 ORDER BY `ticket`, `rankedVoteOption_id`"; if( $this->mysql->query($query) ) { $votes = array(); while( $row = $this->mysql->fetchArray() ) { $votes[$row["ticket"]][$candidates[$row["rankedVoteOption_id"]]] = $row["ranking"]; } } else{ return; } $B = count($votes); //1 pairwise matrix d[CxC] $d = array_fill(0, $C, array_fill(0, $C, 0)); for ($i=0; $i<$C; $i++){ $d[$i][$i] = 0; for($j=$i+1;$j<$C; $j++){ $count1 = 0; $count2 = 0; /* for($k=0; $k<$B; $k++){ if ($votes($k,$i) > $votes($k,$j)){ $count1++; }else if ($votes($k,$i) < $votes($k,$j)){ $count2++; } }*/ foreach($votes as $vote){ if ($vote[$i] < $vote[$j]){ //prefer i to j $count1++; }else if ($vote[$i] > $vote[$j]){ //prefer j to i $count2++; } } $d[$i][$j] = $count1; //sum( votes(i,:) > votes(j,:) ); $d[$j][$i] = $count2; //sum( votes(i,:) < votes(j,:) ); } } //2 strengths of the strongest paths p[CxC] $p = array_fill(0, $C, array_fill(0, $C, 0)); for ($i=0; $i<$C; $i++){ for($j=0;$j<$C; $j++){ //optimize: j=$i+1 if ($i != $j){ if($d[$i][$j] > $d[$j][$i]){ $p[$i][$j] = $d[$i][$j]; } else{ $p[$i][$j] = 0; } } } } for ($i=0; $i<$C; $i++){ for($j=0;$j<$C; $j++){ if ($i != $j){ for($k=0; $k<$C; $k++){ if (($k != $i) && ($k != $j)){ $p[$j][$k] = max($p[$j][$k], min($p[$j][$i] , $p[$i][$k])); } } } } } //find winners $winner = array(); for ($i=0; $i<$C; $i++){ $count = 0; for($j=0;$j<$C; $j++){ if ($p[$i][$j] > $p[$j][$i]){ $count++; } } $winner[$i] = $C - $count; $q = "UPDATE `rankedVoteOptions` SET `ranking`=".$winner[$i]." WHERE `id`=".$candidates_id[$i]; $this->mysql->query($q); } $q = "UPDATE `rankedVote` SET `schultze_d`='".json_encode($d)."', `schultze_p`='".json_encode($p)."' WHERE `id`=".$id; $this->mysql->query($q); } public function loadClosed($agora_id){ $query = 'SELECT * FROM `rankedVote` WHERE `agora_id`="'.$agora_id.'" AND `close` < NOW() AND `published`=1'; if( $this->mysql->query($query) ) { $ret = array(); while( $row = $this->mysql->fetchArray() ) { $row['rankedVoteOptions'] = 'Options'; $row['view'] = 'View'; $ret[$row['id']] = $row; } return $ret; }else { return array(); } } public function getMyLocal($uid){ $query = 'SELECT * FROM `voting_delegates` WHERE `uid`="'.$uid.'" AND agora_id='.$_SESSION['JC_MODULE']['AgoraId']; if( $this->mysql->query($query) ) { $result = $this->mysql->fetchArray(); return $result['bodyCode']; }else { return ''; } } /** * Save or update rankVote: * @param object with the data * @return boolean true in case of success, false otherwise */ public function saveOrUpdate(IModel $rankVote) { $query=""; $recordID=$rankVote->getId(); if($recordID==NULL) { $query.="INSERT INTO `rankedVote` SET "; } else { $query.="UPDATE `rankedVote` SET "; } $query .="`agora_id` = '".$this->mysql->escape($rankVote->getAgora_id())."', "; $query .="`title` = '".$this->mysql->escape($rankVote->getTitle())."', "; $query .="`published` = '".$this->mysql->escape($rankVote->getPublished())."', "; $query .="`open` = '".$this->mysql->escape($rankVote->getOpen())."', "; $query .="`close` = '".$this->mysql->escape($rankVote->getClose())."', "; $query .="`schultze_d` = '".$this->mysql->escape($rankVote->getSchultze_d())."', "; $query .="`schultze_p` = '".$this->mysql->escape($rankVote->getSchultze_p())."'"; if($recordID!=NULL) { $query.=" where `id` = ".$recordID; } return $this->mysql->query($query); } public function get_last_id(){ return $this->mysql->getInsertId(); } } ?>