We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 2734
    • 165 Posts
    Hi all.

    I’m in desperate need for a Poll Module for MODx. I installed the Poll Module by garryn but it doesn’t meet my requirements, since i will use it primarily on multilingual sites. I can’t see any other alternative, so i started to develop a new Poll Module, loosely based on the work by garryn.
    Let me list the planned features so that you might add ideas/wishes while it’s hot...

    Administration (Module for MODX, work in progress)

    • A unlimited amount of polls can be created. done
    • Polls can be limited to a certain date-range (by setting a start- and end-date). done
    • Polls can be set active/inactive. done
    • Polls may consist of a variable amount of possible answers. done
    • The user may setup different languages inside the PollManager. done
    • PollManager will keep track of the current "translation status" by looking up if question and answers are translated for all the poll-languages (if a language isn’t completely translated, it won’t be accessible by the snippet thats responsible for output). done

    Output
    This is basically where i started.. developing a AJAX based replacement for garryns "PollResults" and "PollVote" Snippets. Now it’s just a single snippet, that shows a poll and sends your vote and updates the results via AJAX. This will be extended to work with multiple languages (not too much additional work to do to get there...)

    • Voting and displaying of the results using AJAX. done
    • Degrades/works nicely on a browser without JavaScript. done
    • Works with friendly urls (garryns snippet only worked without the "alias-path"). done
    • Very easy to integrate. Just one Snippet that does all. done
    • Hard-coded text can easily be translated to different languages due to external language-files. done
    • Custom JavaScript callback function to build your own "transition" from vote-screen to the results-screen. done
    • Support for multi-language Polls. done
    • Limiting user to one vote per Poll by setting a cookie and/or logging the IP (same as in garryns module). done
    • Complete customization of Poll appearance with own chunks and css stylesheet. done

    Planned features for later release...

    • Poll Archive

    Dependencies/Requirements

    • MODx 0.9.5 (thats the platform i’m currently developing and testing on)
    • mootools for AJAX functionality
    • PHP5 or higher
    • MySQL Version 4.1 or higher

    Hope this will help somebody when it’s done.
    Cheers -- banal

    Edit (2008-01-29)
    Added some features and the Requirements/Dependencies section.

    Edit (2008-02-01)
    Added some snippet features and changed MySQL Requirements

    Edit (2008-02-05)
    The EasyPoll Module is ready for testing. Have a look at the development thread.
    http://modxcms.com/forums/index.php/topic,22457.0.html
      • 23491 ☆ A M B ☆
      • 1,056 Posts
      @banal,

      I am excited to see what you have come up with! It sounds like a great addition for the community.
        Mike Reid - www.pixelchutes.com
        MODx Ambassador / Contributor
        [Module] MultiMedia Manager / [Module] SiteSearch / [Snippet] DocPassword / [Plugin] EditArea / We support FoxyCart
        ________________________________
        Where every pixel matters.
        • 7253
        • 97 Posts
        This sounds awesome - and saves me the trouble of doing it!!

        I started using the old polls module for a site the other day and decided it needed a re-write but unfortunately I’m totally swamped at the moment. I got as far as re-writing the 2 snippets to output more reasonable markup, adding HTML+CSS bar-chart results and re-doing the CSS.

        This is what the modified poll looks like, if you use my CSS:



        The rounded corners are provided by jQuery and this plugin: http://blue-anvil.com/archives/anti-aliased-rounded-corners-with-jquery

        I’m posting my mods here, in case they’re any use to you:

        pollvote snippet:

        <?php
        // +----------------------------------------------------------------------+
        // | Polls Vote Snippet                                                   |
        // +----------------------------------------------------------------------+
        // | Created: February 2006 Version: 3                                    |
        // +----------------------------------------------------------------------+
        //
        // &pollid	- Poll ID to be used
        // &redirect - Document ID to redirect to (eg Results page)
        // &onevote - Boolean value, if true, uses a cookie to allow only one vote per visitor
        // &useip - Boolean value, if true, logs IP addresses and a user can only have a single vote
        // &ovtime - Time limit to set the cookie time, by default expires in a week
        // &ovmessage - Message to display if a user tries to vote more than once if $onevote/$useip is enabled                     |
        // &resultsbutton - Boolean value, if true, show a 'Results' button - MUST have &redirect defined
        //
        // +----------------------------------------------------------------------+
        
        //-- Try to get poll id, if no poll id then no point carrying on
        if (!isset ($pollid))
        	return false;
        
        $pageID = (isset($_GET['id'])) ? intval($_GET['id']) : $modx->config['site_start'];
        
        //-- set form placeholder
        $cur_url = $modx->makeURL($pageID,$modx->getDocumentIdentifier('alias'),'');
        $modx->setPlaceholder('formaction', $cur_url);
        
        //-- setup initial variables
        $output = '';
        $pollid = intval($pollid);
        $redirect = (isset ($redirect)) ? intval($redirect) : '';
        $onevote = (isset ($onevote)) ? $onevote : 1;
        $ovtime = (isset ($ovtime)) ? $ovtime : 608400; // default: expires in one week
        $useip = (isset ($useip)) ? $useip : 0;
        $ovmessage = (isset ($ovmessage)) ? $ovmessage : 'You are only allowed to vote once';
        $resultsbutton = (isset ($resultsbutton)) ? $resultsbutton : 0;
        $fields = array ();
        
        //-- make url for redirect if required
        if ($redirect <> '') {
        	$doc = $modx->getDocument($redirect);
        	$r_id = $doc['id'];
        	$r_alias = $doc['alias'];
        	$url = $modx->makeURL($r_id, $r_alias,'');
        }
        
        //-- setup DB table names
        $polltable = $modx->getFullTableName("polls");
        $choicetable = $modx->getFullTableName("poll_choices");
        $iptable = $modx->getFullTableName("pollip");
        
        //-- if 'Results' button has been selected
        if (isset ($_POST['results'])) {
        	$modx->sendRedirect($url);
        }
        /*
        	// Debug stuff
        	echo '<h1>onevote: '.print_r($onevote).'</h1>';
        	echo '<h1>poll_pollid: '.$_POST['poll_pollid'].'</h1>';
        	echo '<h1>poll_choice_id: '.$_POST['poll_choice_id()'].'</h1>';
        	echo print_r($_POST);
        */
        //-- if vote was submitted increment polls and poll_choices vote counts
        if (isset ($_POST['vote']) && isset ($_POST['poll_choice_id()'])) {
        
        	//-- cookie check - if $onevote, check if visitor is allowed to vote
        	if ($onevote == true) {
        		if (isset ($_COOKIE['poll' . $_POST['poll_pollid']])) {
        			$novote = true;
        		} else {
        			//-- set cookie
        			setcookie('poll' . $_POST['poll_pollid'], 'novote', time() + $ovtime);
        		}
        	}
        
        	//-- ip check, if $useip, check if visitor is allowed to vote
        	if ($useip == true) {
        		$useraddy = userIP();
        		$results = $modx->db->select('*', $iptable, 'ipaddress=\'' . $useraddy . '\' AND pollid=' . $_POST['poll_pollid'], '');
        		if ($modx->db->getRecordCount($results) > 0) {
        			$novote = true;
        		}
        	}
        	if (!isset ($novote)) {
        		$sql = "UPDATE " . $polltable . " SET votes=votes+1 WHERE id=" . $_POST['poll_pollid'] . ";";
        		$modx->db->query($sql);
        		$sql = "UPDATE " . $choicetable . " SET votes=votes+1 WHERE id=" . $_POST['poll_choice_id()'] . ";";
        		$modx->db->query($sql);
        		//-- log ip address if required
        		if ($useip) {
        			$ipsql = 'INSERT INTO ' . $iptable . ' (pollid,ipaddress) VALUES (' . $pollid . ',\'' . $useraddy . '\')';
        			$modx->db->query($ipsql);
        		}
        		//-- send redirect if required
        		if ($redirect <> '') {
        			$modx->sendRedirect($url);
        		} else {
        			//echo '<h1>Results go here</h1>';
        		}
        	}
        	
        }
        
        //-- query for the poll to be displayed and assign local variables
        $where = "id=" . $pollid;
        $rs = $modx->db->select("*", $polltable, $where, "id ASC", "");
        $limit = $modx->db->getRecordCount($rs);
        if ($limit > 0) {
        	$poll = $modx->db->getRow($rs);
        }
        
        //-- query for poll choice results
        $where = "pollid=" . $pollid;
        $choices_rs = $modx->db->select("*", $choicetable, $where, "id ASC", "");
        $limit2 = $modx->db->getRecordCount($choices_rs);
        
        if ($limit > 0) {
        
        	//-- start the CSS poll voting display
        	$output .= '
        					<form class="poll" name="pollvote" method="post" action="[+formaction+]">
        						<input type="hidden" name="poll_pollid" value="' . $poll['id'] . '" />
        							<h3>' . stripslashes($poll['question']).'</h3>
        							<div>
        					';
        
        	//-- loop through choice results
        	for ($i = 0; $i < $limit2; $i++) {
        		$row = $modx->db->getRow($choices_rs);
        
        		//-- display each poll choice
        		$output .= '
        					<input type="radio" id="poll_choice_'.$i.'" name="poll_choice_id()" value="' . $row['id'] . '" />
        					<label for="poll_choice_id">' . stripslashes($row['choice']) . '</label><br />';
        	}
        
        	//-- display buttons
        	$output .= '</div>'."\n".'<input type="submit" name="vote" value="Vote" class="vote" />';
        	if ($resultsbutton == true && $redirect <> '') {
        		$output .= '<input type="submit" name="results" value="Results" class="vote" />';
        	}
        	if (isset ($novote)) {
        		$output .= '<h3 class="poll_reject">' . $ovmessage . '</h3>';
        	}
        
        	$output .= '</form>';
        }
        
        return $output;
        
        //-- gets the visitors ip address
        function userIP() {
        	// This returns the True IP of the client calling the requested page
        	// Checks to see if HTTP_X_FORWARDED_FOR 
        	// has a value then the client is operating via a proxy
        	if ($_SERVER['HTTP_CLIENT_IP'] <> '') {
        		$userIP = $_SERVER['HTTP_CLIENT_IP'];
        	}
        	elseif ($_SERVER['HTTP_X_FORWARDED_FOR'] <> '') {
        		$userIP = $_SERVER['HTTP_X_FORWARDED_FOR'];
        	}
        	elseif ($_SERVER['HTTP_X_FORWARDED'] <> '') {
        		$userIP = $_SERVER['HTTP_X_FORWARDED'];
        	}
        	elseif ($_SERVER['HTTP_FORWARDED_FOR'] <> '') {
        		$userIP = $_SERVER['HTTP_FORWARDED_FOR'];
        	}
        	elseif ($_SERVER['HTTP_FORWARDED_FOR'] <> '') {
        		$userIP = $_SERVER['HTTP_FORWARDED_FOR'];
        	} else {
        		$userIP = $_SERVER['REMOTE_ADDR'];
        	}
        	// return the IP we've figured out:
        	return $userIP;
        }
        ?>


        pollresults snippet:

        <?php
        // +----------------------------------------------------------------------+
        // | Polls Results Snippet                                                |
        // +----------------------------------------------------------------------+
        // | Created: January 2006 Version: 1                                     |
        // +----------------------------------------------------------------------+
        //
        // &pollid  - Poll ID to be used
        // &decimal - Display decimal places, (number is how many dp's to display)
        //
        // +----------------------------------------------------------------------+
        
        //-- Try to get poll id, if no poll id then no point carrying on
        if (!isset ($pollid))
        	return false;
        
        $output = '';
        $pollid = intval($pollid);
        
        $decimal = (isset ($decimal)) ? intval($decimal) : 1;
        
        //-- Setup DB table names
        $polltable = $modx->getFullTableName("polls");
        $choicetable = $modx->getFullTableName("poll_choices");
        //$resultstable = $modx->getFullTableName('poll_results');
        
        //-- Query for the poll to be displayed and assign local variables
        $where = "id=" . $pollid;
        $rs = $modx->db->select("*", $polltable, $where, "id ASC", "");
        $limit = $modx->db->getRecordCount($rs);
        
        
        if ($limit > 0) {
        	$poll = $modx->db->getRow($rs);
        	$name = $poll['name'];
        	$question = $poll['question'];
        	$totalvotes = $poll['votes'];
        }
        
        //-- Query for poll choice results
        $where = "pollid=" . $pollid;
        $choices_rs = $modx->db->select("*", $choicetable, $where, "id ASC", "");
        $climit = $modx->db->getRecordCount($choices_rs);
        
        
        if ($limit > 0) {
        	//-- Start the CSS poll results display
        	$output .= '
        	<div class="corner poll">
        		<h3>' . stripslashes($question) . '</h3>
        		<hr />
        		<dl class="complex_bar">
        		';
        
        	//-- Loop through choice results
        	for ($i = 0; $i < $climit; $i++) {
        		$row = $modx->db->getRow($choices_rs);
        		$choice = $row['choice'];
        		$votes = $row['votes'];
        
        		if (($votes < 1) || ($totalvotes < 1)) {
        			$percent = 0;
        		} else {
        			$percent = ($votes / $totalvotes) * 100;
        		}
        
        		if ($percent > 0) {
        			$percent = number_format($percent, $decimal, '.', '');
        		}
        
        		//-- Display the details of each poll choice
        		$output .= '<dt>'.stripslashes($choice).'</dt>'."\n";
        		$output .= '<dd><div style="width:'.$percent.'%;"><strong>'.$percent.'%</strong></div></dd>'."\n";
        	}
        
        	//-- Display total votes for the poll so far and close the table
        	$output .= '</dl>
        			<br class="clear" />
        			<h4>Total Votes: [' . $totalvotes . ']</h4>
        		</div>
        	';
        }
        
        return $output;
        ?>


        and here is the CSS (which hasn’t has much cross browser testing and mostly came from here: http://applestooranges.com/blog/post/css-for-bar-graphs/?id=55:)

        /*
        
        	Poll Styles
        
        */
        
        div.corner {
        	width: 50%;
        	padding: 0 1em;
        	background-color: #e5f3ff;
        	border: 1px solid #CBE7FF;
        }
        .poll input[type="radio"] {
        	margin-bottom: 0.25em;
        }
        .poll h3 {
        	font-size: 100%;
        	line-height: 1.2;
        	margin: 0 auto 0.3em auto;
        }
        .poll h4 {
        	font-size: 85%;
        	line-height: 1.1;
        	margin: 0 auto 0.3em auto;
        }
        div.corner form.poll {
        	margin-bottom: 1em;
        }
        
        /* Basic Bar Graph */
        .graph { 
        	position: relative; /* IE is dumb */
        	width: 200px; 
        	border: 1px solid #B1D632; 
        	padding: 2px; 
        	margin-bottom: .5em;
        }
        .graph .bar { 
        	display: block;	
        	position: relative;
        	background: #B1D632; 
        	text-align: center; 
        	color: #333; 
        	height: 2em; 
        	line-height: 2em;
        }
        /* This extra markup is necessary because IE doesn't want to follow the rules for overflow: visible */
        .graph .bar span { position: absolute; left: 1em; }
        
        /* Complex Bar Graph */
        
        dl.complex_bar dt { 
        	position: relative; /* IE is dumb */
        	clear: both;
        	display: block;
        	height: 20px;
        	font-weight: normal;
        }
        dl.complex_bar dd { 
        	position: relative; /* IE is dumb */
        	display: block;
        	float: left;
        	width: 95%;
        	height: 20px;
        	margin: 0 0 5px;
        	background: #fff;
        	border: 1px solid #CBE7FF;
        }
        
        dl.complex_bar dd div { 
        	background-color: #2A567A;
        	background-color: #8AB1CE;
        	position: relative;
        	height: 20px;
        	width: 75%; 
        	text-align:right;
        }
        dl.complex_bar dd div strong { 
        	position: relative;
        	text-align: left;
        	top: -2px;
        	font-size: 80%;
        	margin-right: 0.5em;
        }
        


        Hope this helps, in some small way smiley

        Cheers,
        Dunc
          • 23562
          • 57 Posts
          Wow, thats great banal! I have one wish rolleyes -to be compatible with PHP 4 if that is not too much trouble smiley
          Great news about your poll,cant wait to try it out!
            • 2734
            • 165 Posts
            Hi pixelchutes, dunc and plavet

            Thanks for your replies. The module is coming along nicely. I hope to release a test-version very soon... got other stuff to do at the moment as well.
            I already did a re-write of the Poll Vote Snippet. I’m going to change that in order that the people may customize it’s appearance by chunk-templates and own css. So everybody may style it his own way.

            PHP4 is considered deprecated (no longer supported/maintained by the php developers) and i’m not sure if it makes sense to further develop stuff for php4?
              • 2734
              • 165 Posts
              Hello readers of this post

              I released the EasyPoll Module for testing.
              Read my post in the Development forum to run your own tests smiley

              Please post feedback in the other thread as well!
              http://modxcms.com/forums/index.php/topic,22457.0.html