<?php if (!defined('PmWiki')) exit (); /** * This script allows votings with several items and ouputs a nice graph * * @author Patrick R. Michaud <pmichaud@pobox.com> * @author Sebastian Siedentopf <schlaefer@macnews.de> * @version 0.5a * @link http://www.pmwiki.org/wiki/Cookbook/RyeVoting http://www.pmwiki.org/wiki/Cookbook/RyeVoting * @copyright by the respective authors 2004-2005 * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License * @package ryevote */ /* needs 2.1beta 15 For Developers ============== Version History --------------- * 0.5 - - Schlaefer ** [feature] multiple button fields in form * 0.4.4 - 2006-02-01 - Schlaefer ** [change] removed unnecessary function addone() * 0.4.2 - 2006-01-23 - Schlaefer ** [bugfix] changed drawing for better IE compatibility * 0.4.1 - 2005-10-23 - Schlaefer ** [bugfix] use {$PageUrl} for complete URI in form */ define(RYEVOTE, '0.5'); SDVA($PmWikiAutoUpdate['RyeVote'] , array( 'version' => RYEVOTE, 'updateurl' => "http://pmwiki.org/wiki/Cookbook/RyeVoting" )); SDV($HandleActions['ryevote'], 'HandleRyeVote'); SDV($HandleAuth['ryevote'], 'read'); SDV($RyeVoteHideAfterVote, 1); SDV($RyeVoteRestrictions, 1); SDV($RyeVoteCookie, $CookiePrefix.'ryevote'); SDV($RyeVoteExpires, $Now +60 * 60 * 24 * 30); SDV($RyeVoteDBPName, "Site.RyeVoteDB"); SDV($RyeVoteDir, '/'); Markup('showryevote', '<split', '/(\(:input form.*?action=ryevote.*?input end:\))/se', "showRyeVote(PSS('$0'))"); /** * Belongs to Markup "showryevote" and hides the vote input form if someone already voted * * @param string $text */ function showRyeVote($text) { global $RyeVoteCookie, $RyeVoteHideAfterVote, $RyeVoteDBPName, $RyeVoteRestrictions; preg_match("/\(:input hidden votename\s*(.*?)\s*?:\)/", $text, $votename); $dbname = (preg_match("/\(:input hidden db\s*(.*?)\s*?:\)/", $text, $r)) ? $r[1] : $RyeVoteDBPName; $db = new PmWikiPageDB($dbname); $data = $db->ReadData(); $cookiename = $RyeVoteCookie.$votename[1]; if ((isset ($_COOKIE[$cookiename]) || strpos($data['ryevote'][$votename[1]]['ipsvoted'],$_SERVER['REMOTE_ADDR']) != false) && $RyeVoteHideAfterVote && $RyeVoteRestrictions) return ""; else return $text; } /** * Handles the voting process * * @param string $pagename */ function HandleRyeVote($pagename, $auth = 'edit') { global $HandleActions, $ChangeSummary, $RyeVoteCookie, $RyeVoteExpires, $RyeVoteDir, $RyeVoteDBPName, $RyeVoteRestrictions; if (!isset ($_REQUEST['votename'])) Redirect($pagename); Lock(1); $page = RetrieveAuthPage($pagename, $auth); Lock(0); if (!$page) Abort("?cannot edit $pagename"); # find all vote input forms on a wiki page preg_match_all("/\\(:input form.*?action=ryevote(.*?)\\(:input end:\\)/s",$page['text'], $votes); $votename = $_REQUEST['votename']; foreach ($votes[0] as $key => $text) { # searchs the vote form in question, if there are more then one on a wiki page if (!preg_match("/\(:input hidden votename\s*".$votename."/", $text)) continue; $cookiename = $RyeVoteCookie.$votename; if (!isset ($_COOKIE[$cookiename])) setcookie($cookiename, "true", $RyeVoteExpires, $RyeVoteDir); elseif ($RyeVoteRestrictions) Redirect($pagename); # searchs for the label and values in the vote form preg_match_all("/\(:input radio ([^\\s]*?)\\s*?([^\\s]*?)\s*?:\)(.*?)(\n|\(:|\\\\)/", $text, $options); $dbname = ($_POST['db']) ? $_POST['db'] : $RyeVoteDBPName; $db = new PmWikiPageDB($dbname); $data = $db->ReadData(); if (!$data['ryevote'][$votename]) { for ($i = 0; $i<count($options[1]); $i++){ $data['ryevote'][$votename][$options[1][$i]]['setname'] = $_POST[$options[1][$i]."-name"]; $data['ryevote'][$votename][$options[1][$i]][$options[2][$i]]['name'] = $options[3][$i]; $data['ryevote'][$votename][$options[1][$i]][$options[2][$i]]['value'] = 0; } } if ((strpos($data['ryevote'][$votename]['ipsvoted'],$_SERVER['REMOTE_ADDR']) != false)) Redirect($pagename); elseif ($RyeVoteRestrictions) $data['ryevote'][$votename]['ipsvoted'] .= " {$_SERVER['REMOTE_ADDR']}, "; foreach ($_POST as $set => $id) if ($data['ryevote'][$votename][$set][$id]) $data['ryevote'][$votename][$set][$id]['value'] +=1; $db->WriteData($data); } if ($_POST['redirect']) $pagename = $_POST['redirect']; Redirect($pagename); } Markup('ryevotediagramm', '<split', "/\\(:ryevote\\s(.*?):\\)/e", "RyeVoteDrawDiagramm('$1')" ); /** * Handles the drawing of the votes. * * @param string $args */ function RyeVoteDrawDiagramm($args) { global $RyeVoteDBPName; $out = "\n"; $pargs = ParseArgs($args) ; $dbname = ($pargs['db']) ? $pargs['db'] : $RyeVoteDBPName; $db = new PmWikiPageDB($dbname); $data = $db->ReadData(); if (!$data) return; foreach($data['ryevote'][$pargs['votename']] as $set => $id) { if ($set == "ipsvoted") continue; $setnames = $names = $values = array(); foreach($id as $k => $value){ if ($k != "setname") { $values[] = $value['value']; $names[] = $value['name']; } else $setnames[$set] = $value; } # install your own fancy drawing code here # values ar in values[], names in names[] and headings in []setnames foreach($setnames as $set => $setname) { $out .= "<br/><br/>\n$setname"; if (($sum = array_sum($values)) != 0) $sum = 100 / $sum; $out .= "%define=ryevotebox display=block bgcolor=silver color=silver%\n"; $out .= "(:table:)\n"; foreach ($names as $k => $v) { $percentage = floor($values[$k] * $sum); $upbound = $percentage * 4; $out .= "(:cellnr:)".$names[$k]."\n(:cell:)%ryevotebox width=".$upbound."px%.\n"; $out .= "(:cell style=\"color:gray;\":) (".$values[$k]."/".$percentage."%)\n"; } $out .= "(:tableend:) \n"; } } return $out; } class PmWikiPageDB { var $dbpname; var $sep = ' => '; function PmWikiPageDB($pagename) { $this->dbpname = $pagename; } function ReadData(){ Lock(1); $page = ReadPage($this->dbpname, READPAGE_CURRENT); Lock(0); $data = $page['text']; $lines = explode("\n", $data); $stack = array(); foreach($lines as $line){ if (!preg_match("/^([#*]+)(.*)$/", $line, $match)) continue; if ($match[1]{0} == "#") { while (count($stack) >= strlen($match[1])) array_pop($stack); array_push($stack, $match[2]); continue; } else { $p = '$out'; foreach($stack as $st) $p .= "['$st']"; $p .= str_replace($this->sep, "='", $match[2])."';"; eval ($p); array_pop($stack); } } return $out; } function WriteData($newdata, $mode = "w") { global $EnablePost, $Now; Lock(2); $page = ReadPage($this->dbpname); $new = $page; $new['text'] = $this->generateData($newdata); $new['time'] = $Now; $EnablePost = true; PostPage($this->dbpname, $page, $new); Lock(0); } function generateData($newdata, $depth = 0, $pre = "") { $depth ++; if ($depth < 5) $out .= str_repeat("!", $depth+1)." \n"; foreach($newdata as $key => $value) if (is_array($value)) { $out .= str_repeat("#",$depth)."$key\n"; $out .= $this->generateData($value, $depth); } else { $out .= str_repeat("#",$depth)."$key\n"; $out .= str_repeat("*",$depth+1)."$this->sep$value\n"; } return $out; } } ?>