<?PHP
define( "patPOLLS_RANDOM", 1 );
define( "patPOLLS_SHORTEST", 2 );
define( "patPOLLS_LONGEST", 3 );
/**
* patPolls poll management system
*
* Features inlude: Multiple answers, write-ins, manage several polls at once
*
* @package patPolls
* @access public
* @author Stephan Schmidt <hide@address.com>, Sebastian Mordziol <hide@address.com>
* @version 1.1
*/
class patPolls {
var $options = array( "selectionType" => "date",
"selectionValue" => "current",
"selectionMode" => patPOLLS_RANDOM );
var $querytable, $answertable;
var $poll_id;
var $poll_content;
var $poll_error = array();
/**
* Constructor, does some init routines
*
* @access public
* @param string $name name of the poll, to identify forms, buttons, etc.
*/
function patPolls( $name, $prefix ) {
$this->name = $name;
$this->querytable = $prefix."_pollsquery";
$this->answertable = $prefix."_pollsanswer";
}
/** -- Copy of patDbc function --
* Added by F.o.G.
* get the complete result as two dimensional array
*
* @access public
* @param int $result_type type of result (patDBC_TYPEBOTH, patDBC_TYPEASSOC, patDBC_TYPENUM)
* @return array $data result
*/
function get_result( $result_type ) {
$i = 0;
while ( $row = mysql_fetch_array( $result_type ) ) {
$data[$i] = $row;
$i++;
}
return $data;
}
/** Added by F.o.G.
* Sets the object that handles IP Checks and so on
*
* @access public
*/
function setIPObject(&$object) {
$this->ipObject = &$object;
}
/**
* set the patTemplate object for the output of the polls
*
* @access public
* @param object patTemplate $template Template Object
*/
function setTemplate( $template )
{
$this->template = $template;
}
/**
* set the renderer object for the polls
*
* @access public
* @param object patRenderer $renderer Renderer Object
*/
function setRenderer( $renderer )
{
// meikelator note: following function takes args by reference by default ...
$renderer->setPollReference( $this ); // ... so do not try to reference the pointer address (happily it won't work anyway)
$this->renderer = $renderer;
}
/**
* set the name of the MySQL table where the poll data is stored
*
* @access public
* @param string $querytable name of the query table
*/
function setQuerytable( $querytable )
{
$this->querytable = $querytable;
}
/**
* set the name of the MySQL table, where the answers are stored
*
* @access public
* @param string $answertable name of the answers table
*/
function setAnswertable( $answertable )
{
$this->answertable = $answertable;
}
/**
* set a patPoll Option
*
* @access public
* @param string $option option to be set
* @param mixed $value value of the option
*/
function setOption( $option, $value )
{
$this->options[$option] = $value;
}
/**
* get a patPoll Option
*
* @access public
* @param string $option option to be set
* @return mixed $value value of the option
*/
function getOption( $option )
{
return $this->options[$option];
}
/**
* process a poll and display the resulting HTML content
*
* @access public
*/
function getPollContent()
{
if($this->poll_error[noValidPoll] != true) {
$this->poll_content = $this->getPoll();
}
}
/**
* returns the poll contnet
*
* @access public
*/
function displayPollContent() {
if(count($this->poll_error) == 0) {
return $this->poll_content;
} else {
return false;
}
}
/**
* process a poll and return the resulting HTML content
*
* @access public
*/
function getPoll()
{
global $HTTP_GET_VARS, $HTTP_POST_VARS;
$this->parseVariables( $HTTP_GET_VARS );
$this->parseVariables( $HTTP_POST_VARS );
switch( $this->variables[action] )
{
case "vote":
$this->processVote();
return $this->renderer->start();
break;
default:
switch( $this->getOption( "selectionType" ) )
{
case "id":
$this->selectPollById( $this->getOption( "selectionValue" ) );
break;
case "date":
$this->selectPollByDate( $this->getOption( "selectionMode" ), $this->getOption( "selectionValue" ) );
break;
}
$this->loadData();
return $this->getQuery();
break;
}
}
/**
* process a vote by the user
*
* @access private
*/
function processVote() {
$this->selectPollById( $this->variables[id] );
$this->loadData();
// Check, wether user really voted
if( isset( $this->variables[answer] ) ) {
// update users information
$this->querydata[users]++;
if( !is_array( $this->variables[answer] ) ) {
$this->variables[answer] = (array) $this->variables[answer];
}
for( $i=0; $i<count( $this->variables[answer] ); $i++ ) {
if( $this->variables[answer][$i] != "write_in" ) {
for( $j=0; $j<count( $this->answerdata ); $j++ )
if( $this->answerdata[$j][id] == $this->variables[answer][$i] )
$this->answerdata[$j][count]++;
} else {
$new_writein = true;
for( $j=0; $j<count( $this->writeindata ); $j++ ) {
if( $this->writeindata[$j][answer] == $this->variables[writein] ) {
$this->writeindata[$j][count]++;
$new_writein = false;
}
}
if( $new_writein ) {
$this->writeindata[] = array( "id" => "new", "answer" => $this->variables[writein], "count" => 1 );
}
}
}
}
$lockUser = false;
if($this->ipLockStatus) {
$lockUser = $this->ipObject->checkIPLock($this->poll_id);
}
if(!$lockUser) {
$this->saveData();
}
}
/**
* parse HTTP variables of the poll into array
*
* @access private
*/
function parseVariables( $vars )
{
if( !is_array( $vars ) )
return false;
$prefix = $this->name."_";
$prefixlength = strlen( $prefix );
reset( $vars );
while ( list ( $key, $val ) = each( $vars ) )
{
if ( substr( $key, 0, $prefixlength ) == $prefix )
$this->variables[substr( $key, $prefixlength )] = $val;
}
}
/**
* select a query by a given ID
*
* @access private
* @param int $id ID of the poll
* @see selectPollByDate()
*/
function selectPollById( $id )
{
// Existiert eine Umfrage mit dieser ID in der Datenbank?
$query = "SELECT id FROM ".$this->querytable." WHERE id='".$id."' AND active='yes'";
$result = mysql_query($query);
if ( mysql_num_rows($result) != 1 )
die ( "Couldn't select unique Poll by ID ".$id."." );
$this->poll_id = $id;
}
/**
* select a query by a given date
*
* @access private
* @param int $mode mode for selecting a poll, if more than one valid poll was found
* @param string $date date in MySQL format (YYYY-MM-DD HH:MM:SS)
* @see selectPollByID()
*/
function selectPollByDate( $mode = patPOLLS_RANDOM, $date = "current" )
{
// Wenn kein Datum angegeben ist, das aktuelle holen
if ( $date=="current" )
$date = date( "Y-m-d H:i:s", time() );
// Alle Umfragen aus der Datanbank holen, die aktiv und am gewünschten Datum gültig sind
$query = "SELECT id,valid_from,valid_until FROM ".$this->querytable." WHERE active='yes' AND valid_from<='".$date."' AND valid_until>='".$date."'";
switch( $mode )
{
// Die Umfrage holen, deren Ende als nächstes kommt => kann auch auf eine Zeile begrenzt werden
case patPOLLS_SHORTEST:
$query .= " ORDER BY valid_until ASC LIMIT 0,1";
break;
// Die Umfrage holen, ie noch am längsten läuft => kann auch auf eine Zeile begrenzt werden
case patPOLLS_LONGEST:
$query .= " ORDER BY valid_until DESC LIMIT 0,1";
break;
}
$result = mysql_query($query);
switch ( $polls = mysql_num_rows($result) )
{
// Keine Umfrage gefunden
case 0:
$this->pollError[noValidPoll] = true;
break;
// Genau eine Umfrage gefunden => perfekt
case 1:
$row = mysql_fetch_array($result);
$this->poll_id = $row[id];
break;
// Es passen mehr als eine Umfrage auf die gewünschten Kriterien
// jetzt muss der Parameter mode greifen
default:
switch( $mode )
{
// Eine Umfrage per Zufallsgenerator auswählen
case patPOLLS_RANDOM:
// Alle Umfragen aus der DB holen
$i = 0;
while ( $data[$i] = mysql_fetch_array($result) )
$i++;
// Zufallszahl holen
srand((double)microtime()*1000000);
$r = rand(0, ($polls-1) );
// Aus der zufällig gewählten Zeile die ID holen
$this->poll_id = $data[$r][id];
break;
// Bei anderen Modes einfach die erste Zeile nehmen => Fehlerkorrektur
default:
$row = mysql_fetch_array($result);
$this->poll_id = $row[id];
break;
}
break;
}
}
/**
* load all data for the selected Poll from the database
*
* @access private
*/
function loadData()
{
if ( $this->poll_id ) {
// Get all query data
$query = "SELECT * FROM ".$this->querytable." WHERE id='".$this->poll_id."'";
$result = mysql_query($query);
$this->querydata = mysql_fetch_array($result);
mysql_free_result($result);
// Check, if the answers should be sorted
if( $this->checkPollOption( "order_query" ) )
$order = " ORDER BY answer";
else
$order = " ORDER BY id";
// Get all default answers
$query = "SELECT * FROM ".$this->answertable." WHERE poll='".$this->poll_id."' AND type='default'".$order;
$result = mysql_query($query);
$this->answerdata = $this->get_result( $result );
mysql_free_result($result);
// Get all writeins
$query = "SELECT * FROM ".$this->answertable." WHERE poll='".$this->poll_id."' AND type='writein'";
$result = mysql_query($query);
$this->writeindata = $this->get_result( $result );
mysql_free_result($result);
}
}
/**
* get all query data
* @access public
* @return array $querydata return all querydata in a associative array
*/
function getQueryData()
{
return $this->querydata;
}
/**
* get all default answer data
* @access public
* @return array $answerdata return all answerdata in a associative array
*/
function getAnswerData()
{
$data = $this->answerdata;
if( $this->checkPollOption( "order_result" ) )
usort( $data, "patPollsSortAnswers" );
return $data;
}
/**
* get all writeins answer data
* @access public
* @return array $writeindata return all writeindata in a associative array
*/
function getWriteinData()
{
return $this->writeindata;
}
/**
* check, wether an option is set
* @access public
* @param string $option name of the option
* @return bool $set true, if the option is set, false otherwise
*/
function checkPollOption( $option )
{
$pos = strpos ( $this->querydata[options], $option );
if( $pos == 0 && !is_int( $pos ) )
return false;
return true;
}
/**
* save all data for the selected Poll into the database
*
* @access private
*/
function saveData() {
// Save querydata
$query = "UPDATE ".$this->querytable." SET ";
reset( $this->querydata );
while( list( $key, $value ) = each( $this->querydata ) ) {
if( !is_int( $key ) )
$query .= $key."='".addslashes( $value )."', ";
}
// cut last comma
$query = substr( $query, 0, strlen( $query )-2 );
// Add where clause => don't update all entries in table
$query .= " WHERE id=".$this->poll_id;
mysql_query($query);
// Save answerdata
for( $i=0; $i<count( $this->answerdata ); $i++ ) {
$query = "UPDATE ".$this->answertable." SET ";
reset( $this->answerdata[$i] );
while( list( $key, $value ) = each( $this->answerdata[$i] ) ) {
if( !is_int( $key ) )
$query .= $key."='".addslashes( $value )."', ";
}
// cut last comma
$query = substr( $query, 0, strlen( $query )-2 );
// Add where clause => don't update all entries in table
$query .= " WHERE id=".$this->answerdata[$i][id];
// send to db
mysql_query($query);
}
// Save writeindata
for( $i=0; $i<count( $this->writeindata ); $i++ ) {
if( $this->writeindata[$i][id] != "new" ) {
$query = "UPDATE ".$this->answertable." SET ";
reset( $this->writeindata[$i] );
while( list( $key, $value ) = each( $this->writeindata[$i] ) )
{
if( !is_int( $key ) )
$query .= $key."='".addslashes( $value )."', ";
}
// cut last comma
$query = substr( $query, 0, strlen( $query )-2 );
// Add where clause => don't update all entries in table
$query .= " WHERE id=".$this->writeindata[$i][id];
} else {
$query = "INSERT INTO ".$this->answertable."(poll, answer, type, count) VALUES('".$this->poll_id."', '".addslashes( $this->writeindata[$i][answer] )."', 'writein',1 ) ";
}
// send to db
mysql_query($query);
}
if($this->ipLockStatus) {
$this->ipObject->setIPEntry($this->poll_id);
}
}
/**
* display a query
*
* @access private
*/
function getQuery()
{
// Add name global to all templates
$this->template->assign( "PP_NAME", $this->name );
// Add all query related data
if(is_array($this->querydata)) {
foreach($this->querydata as $k => $v) {
$queryData["PP_".$k] = $v;
}
}
$this->template->assign( "poll_query", $queryData);
// Add all possible answers
$cnt_rows = count( $this->answerdata );
for ( $i = 0; $i < $cnt_rows; $i++ ) {
if( is_array( $this->answerdata[$i] ) ) {
// Get key and value
while( list( $key,$value ) = each( $this->answerdata[$i] ) ) {
// check if the array key is an int value => skip it
if ( !is_int( $key ) ) {
// prepend prefix and store the value
$answerData[$key][] = $value;
}
}
}
}
$this->template->assign( "poll_error", $this->pollError[noValidPoll] );
$this->template->assign( "poll_answer", $answerData );
if( $this->checkPollOption( "allow_write_ins" ) ) {
// Display write in template
$this->template->assign( "poll_write_in_set", "1" );
}
return $this->template->fetch( "patPollsQuery.tmpl", "", "", true );
}
}
?>