Topic: Developing new Poll Module for MODx [Now Ready for testing]  (Read 2507 times)

Pages: [1]   Go Down

#1: 29-Jan-2008, 11:31 AM

banal
Posts: 165

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
« Last Edit: 5-Feb-2008, 03:49 AM by banal »

#2: 29-Jan-2008, 11:52 AM

Coding Team

pixelchutes
Posts: 889

WWW
@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 Team Member / Contributor
[Module] MultiMedia Manager / [Module] SiteSearch / [Snippet] DocPassword / [Plugin] EditArea / We support FoxyCart
________________________________
Where every pixel matters.

#3: 31-Jan-2008, 08:37 PM


dflock
Posts: 77

WWW
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:

Code:
<?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:

Code:
<?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:)

Code:
/*

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

#4: 31-Jan-2008, 10:26 PM

plavet
Posts: 57

Wow, thats great banal! I have one wish Roll Eyes -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!

#5: 1-Feb-2008, 04:34 AM

banal
Posts: 165

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?

#6: 5-Feb-2008, 03:29 AM

banal
Posts: 165

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

Pages: [1]   Go Up
0 Members and 1 Guest are viewing this topic.