Location: PHPKode > scripts > Actionpoll > actionpoll_1.1.1/actionpoll-1.1.1/actionpoll.php
<?php 
// ActionPoll V1.1.1 
// Author: robert ladstaetter <hide@address.com>

// This software is licensed under GPL, see the www.fsf.org 
// for details or read gpl.txt distributed with this package.
// It would be nice however to inform me if you use the script 
// and find it useful.

// IMPORTANT: change config.php to fit paths etc. with your configuration!

include("./config.php");

// 
//include($CONFIG_POLLDB);

// ------------------------- begin of configuration -----------------------
// IMPORTANT: if you use the dbPoll you don't need to include following file:
include($CONFIG_TEXTCONFIG); 


// ----------------------------------------------------------------------
// ------------------------- end of configuration -----------------------
// ----------------------------------------------------------------------


// class Actionpoll combines behaviour common to all polls

// Implementation notice: all methods with "_" are internal methods

class ActionPoll {

  var $polldata;
  var $pollSummaryText;
  var $pollTitle;
  var $pollDenyMessage;
  var $pollInternalTitle;
  var $pollStartValue;
  var $pollMaxValue;

  var $totalVotes;
  var $performAction;
  var $pollConfig;
  var $caller;
  var $performIPBan;
  var $pollTimeGap;

  // ---------------------------------------------------------------------
  // function getDebugHTML
  //
  // $config ... a PollData() object
  //
  // constructor; sets necessary values

  function ActionPoll ($config) {
    global $CONFIG_TEXTCONFIG; //weired PHP 
    $this->polldata          = $config->polldata;
    $this->pollSummaryText   = $config->pollSummaryText;
    $this->pollTitle         = $config->pollTitle;
    $this->pollDenyMessage   = $config->pollDenyMessage;
    $this->pollInternalTitle = $config->pollInternalTitle;
    $this->totalVotes        = $this->calcTotalVotes_();
    $this->performAction     = $config->performAction;
    $this->pollStartValue    = $config->pollStartValue;
    $this->pollMaxValue      = $config->pollMaxValue;
    $this->pollTimeGap       = $config->pollTimeGap;
    $this->pollConfig        = $CONFIG_TEXTCONFIG;

    $this->caller            = gethostbyaddr(getenv("REMOTE_ADDR"));
    $this->performIPBan      = $config->performIPBan;
  }

  // ---------------------------------------------------------------------
  // function getDebugHTML
  //
  // debugging function, prints out variables in HTML code
  function getDebugHTML() {
    return sprintf("<table>".
		   "<tr><td>polldata</td><td>%s</td></tr>" .
		   "<tr><td>pollSummaryText</td><td>%s</td></tr>" .
		   "<tr><td>pollTitle</td><td>%s</td></tr>" .
		   "<tr><td>pollDenyMessage</td><td>%s</td></tr>" .
		   "<tr><td>pollInternalTitle</td><td>%s</td></tr>" .
		   "<tr><td>pollStartValue</td><td>%s</td></tr>" .
		   "<tr><td>pollMaxValue</td><td>%s</td></tr>" .
		   "<tr><td>totalVotes</td><td>%s</td></tr>" .
		   "<tr><td>performAction</td><td>%s</td></tr>" .
		   "<tr><td>pollConfig</td><td>%s</td></tr>" .
		   "<tr><td>caller</td><td>%s</td></tr>" .
		   "<tr><td>performIPBan</td><td>%s</td></tr>" .
		   "<tr><td>pollTimeGap</td><td>%s</td></tr></table>",
		   $this->polldata,
		   $this->pollSummaryText,
		   $this->pollTitle,
		   $this->pollDenyMessage,
		   $this->pollInternalTitle,
		   $this->pollStartValue,
		   $this->pollMaxValue,
		   $this->totalVotes,
		   $this->performAction,
		   $this->pollConfig,
		   $this->caller,
		   $this->performIPBan,
		   $this->pollTimeGap);


  }

  // ---------------------------------------------------------------------
  // function process($vote)
  //
  // $vote ... integer which indicates the number of the chosen option in
  //           the poll
  //
  // heart of actionpoll, here it is decided what to do

  function process($vote) {
    if (!($vote < 0 || $vote >= count($this->polldata) )) {

      if(!($this->increaseVoteIfAllowed_($vote))) {
	printf("<center>" . $this->pollDenyMessage . "</center>");
      }
      $this->totalVotes = $this->calcTotalVotes_(); // we have a new vote now
      if ($this->isMaxReached_($vote) && $this->performAction) {
	print($this->getMaxReachedMessage_());
	$this->maxReachedAction_($vote);
	$this->resetPoll_();
      } else {
	print($this->getShowHTMLMessage());
      }
      $this->writePoll_($vote); 
    } else {
      print("<p>Wrong Value of Parameter!</p>"); 
    }
  }


  // ---------------------------------------------------------------------
  // function increaseVoteIfAllowed_($vote)
  //
  // $vote ... integer which indicates the number of the chosen option in
  //           the poll
  //
  // checks whether or not the voter has voted before and
  // increases counter if not. if voted before, it returns false, else true
  function increaseVoteIfAllowed_($vote)  {
    if (!($this->votedBefore_($vote))) {
      $this->polldata[$vote]["counter"]++;
      array_push($this->polldata[$vote]["ips"],$this->caller);
      array_push($this->polldata[$vote]["timestamp"],time());
      return true;
    } else { 
      return false; 
    }
  }


  // ---------------------------------------------------------------------
  // function getLastVoteTime($ips,$timestamp,$maxtime,$caller)
  //
  // $ips       ... 
  // $timestamp ...
  // $maxtime   ... 
  // $caller    ...
  //
  // checks whether or not voter has voted before and
  // increases counter if not. if voted before, it simply does nothing.
  // gives back timestamp of last vote of this host
  // -1 if there was no vote before 
  function getLastVoteTime($ips,$timestamp,$maxtime,$caller) {
   for ($i=0;$i<count($ips);$i++) { 
     if ($ips[$i] == $caller) {
        if ($maxtime < $timestamp[$i]) {
            $maxtime = $timestamp[$i];
        }
     }
   }
   return $maxtime;
  }

  // ---------------------------------------------------------------------
  // function votedBefore_($vote)
  //
  // $vote ... integer which indicates the number of the chosen option in
  //           the poll
  //
  // returns true if there was a vote before
  // false if the caller is allowed to vote (very logic :( )

  function votedBefore_($vote) {
   $lastVotedTime = -1;
   if ($this->performIPBan) {
     for ($i=0; $i<count($this->polldata);$i++) {
        $lastVotedTime = $this->getLastVoteTime(
                                  $this->polldata[$i]["ips"],
                                  $this->polldata[$i]["timestamp"],
                                  $lastVotedTime,
                                  $this->caller);
     }
     if ($lastVotedTime != -1) {
       $timeGap = time() - $lastVotedTime;
       //printf("<b>debug: time: %s, timegap: %s, lastvisittime: %s</b>",
       //        time(),$timeGap, $lastVotedTime);
       if ($timeGap < $this->pollTimeGap) { 
         return true;
       } else {
         return false;
       }
     }
   } else { 
    return false; // do not check for allowed votes
   }
 } 


  // ---------------------------------------------------------------------
  // function calcTotalVotes_()
  //
  // calculates the sum of votes for every option 

  function calcTotalVotes_() {
    $tmpCountVotes = 0;
    for ($i=0;$i<count($this->polldata); $i++) {
      $tmpCountVotes += $this->polldata[$i]["counter"];
    }
    return $tmpCountVotes;
  }


  // ---------------------------------------------------------------------
  // function resetPoll_()
  //
  // sets internal poll state to the default values
  function resetPoll_() {
    for ($i=0; $i<count($this->polldata); $i++) {
      $this->polldata[$i]["counter"] = $this->pollStartValue;
      $this->polldata[$i]["ips"] = array("");
      $this->polldata[$i]["timestamp"] = array("");
    }
  }

  // ---------------------------------------------------------------------
  // function maxReachedAction_()
  //
  // override this function in subclass - this function gets called if
  // a certain number of votes is reached for one option
  function maxReachedAction_() {
    print("<h1>ActionPoll::maxReachedAction_: IMPLEMENT ME!!!!!!!!!!!</h1>");
  }

  // ---------------------------------------------------------------------
  // function maxReachedAction_()
  //
  // $vote ... integer which indicates the number of the chosen option in
  //           the poll
  // 
  // returns true if the number of polls is greater than the allowed
  // number which is specified in pollMaxValue

  function isMaxReached_($vote) {
    return $this->polldata[$vote]["counter"] >= $this->pollMaxValue;
  }

  // ---------------------------------------------------------------------
  // function generateConfigFile_()
  //
  // returns a string which describes the actual state of the poll
  // in PHP Code.
  function generateConfigFile_() {
    $cfgData = "<?php\n// This is a generated file by actionpoll V1.2.0\n".
      "class PollData { \n var \$polldata = array (\n";
    for ($i = 0; $i < count($this->polldata); $i++) {
      $cfgData .= sprintf("\t\tarray(\n\t\t\t\"item\" => \"%s\",\n". 
			  "\t\t\t\"counter\" => %s,\n" .
			  "\t\t\t\"ips\" => array(\"%s\"),\n".
			  "\t\t\t\"timestamp\" => array(\"%s\")\n\t\t),\n",
			  $this->polldata[$i]["item"],
			  $this->polldata[$i]["counter"],
			  implode("\",\"",$this->polldata[$i]["ips"]),
			  implode("\",\"",$this->polldata[$i]["timestamp"]));
    }
    $cfgData = substr($cfgData,0,-2);
    $cfgData = $cfgData . ");\n";
    $cfgData = sprintf("%s  var \$pollSummaryText = \"%s\";\n".
		       "  var \$pollTitle = \"%s\";\n" .
		       "  var \$pollDenyMessage = \"%s\";\n" .
		       "  var \$pollInternalTitle = \"%s\";\n" .
		       "  var \$pollStartValue = %d;\n" .
		       "  var \$pollMaxValue   = %d;\n".
		       "  var \$pollTimeGap    = %d;\n".
		       "  var \$performAction  = %s;\n".
		       "  var \$performIPBan   = %s;\n}\n?>\n",
		       $cfgData,
		       $this->pollSummaryText,
		       $this->pollTitle,
		       $this->pollDenyMessage,
		       $this->pollInternalTitle,
		       $this->pollStartValue,
		       $this->pollMaxValue,
		       $this->pollTimeGap,
		       $this->performAction,
		       $this->performIPBan);
    return $cfgData; 
  }

  // ---------------------------------------------------------------------
  // function writePoll_($vote)
  //
  // $vote ... integer which indicates the number of the chosen option in
  //           the poll
  //
  // writes state of poll to harddisc (synchronized)
  function writePoll_($vote) {
    $cfgFile = fopen($this->pollConfig,"w");
    flock($cfgFile,2); // aquire exclusive writer lock
    fwrite($cfgFile,$this->generateConfigFile_());
    flock($cfgFile,3); // release lock
    fclose($cfgFile);
  }

  // ---------------------------------------------------------------------
  // In PHP there exists no possibility to force the user to implement
  // certain methods in the subclass, thats why the following 
  // stubs are here. 
  // ---------------------------------------------------------------------

  function getVoteHTMLMessage() {
    return "<h1>ActionPoll::getVoteHTMLMessage()</h1><p>This function gets called when.</p>\n";
  }

  function getShowHTMLMessage() {
    return "<h1>ActionPoll::getVoteHTMLMessage()</h1>" .
      "<p>This function should be implemented to return a HTML formatted form (see for example HTMLActionpoll).</p>\n";
  }

  function getMaxReachedMessage_() {
    return "<h1>ActionPoll::getMaxReachedMessage()</h1>" . 
      "<p>Returns a string which should be displayed when an action takes place.</p>\n";
  }

  function maxReachedAction_() {
    print("<h1>ActionPoll::getmaxReachedAction_()</h1>" .
	  "<p>Fill this function with the PHP commands which are called when a action takes place.</p>\n");
  }

}

// -----------------------------------------------------------------------
// Following class implements an example poll.
// -----------------------------------------------------------------------
// class HTMLActionPoll for dealing with HTML output

class HTMLActionPoll extends ActionPoll {

  var $messageMaxReached;
  var $pollVoteButtonDescription;
  var $pollImage;
  var $pollImageHeight;
  var $pollImageScale;

  function HTMLActionPoll($polldata) {
    global $CONFIG_PIXEL;
    global $CONFIG_IMAGEHEIGHT;
    global $CONFIG_IMAGESCALE;
    $this->ActionPoll($polldata);
    $this->messageMaxReached = "Message which should be displayed at max!";
    $this->pollVoteButtonDescription = "vote!";
    $this->pollImage = $CONFIG_PIXEL; 
    $this->pollImageHeight = $CONFIG_IMAGEHEIGHT;
    $this->pollImageScale  = $CONFIG_IMAGESCALE;
  }

  // HTML Input Form which calls again script
  function getVoteHTMLMessage() {
    global $PHP_SELF; // unhide PHP_SELF
    $voteHTMLMessage  = sprintf("<form action=\"%s\">\n",$PHP_SELF);
    $voteHTMLMessage .= sprintf("<table class=\"pollTable\" align=\"center\">\n");
    $voteHTMLMessage .= sprintf("<tr><td colspan=\"4\" class=\"pollTitle\">%s</td></tr>\n",
			   $this->pollTitle);
    for ($i=0;$i<count($this->polldata); $i++) {

      $percent = ($this->totalVotes != 0)?
	(100 / $this->totalVotes * $this->polldata[$i]["counter"]):
	0;

      $voteHTMLMessage .= sprintf(" <tr> \n".
	     "  <td class=\"pollItem\">%s</td>\n".
	     "  <td class=\"pollOption\"><input type=radio name=\"%s\"".
	     " value=\"%d\"></td>\n" .
	     " </tr>\n",
	     $this->polldata[$i]["item"],
	     $this->pollInternalTitle,
	     $i);
    }
    $voteHTMLMessage .= sprintf(" <tr>\n" .
	   "  <td class=\"pollSummary\" colspan=\"4\"><input type=\"submit\"".
	   "value=\"%s\"></td>" .
	   " </tr>\n</table>\n</form>\n",
	   $this->pollVoteButtonDescription);
    return $voteHTMLMessage;
  }

  function getShowHTMLMessage() {
   
    $showPollStr = "<table class=\"pollTable\" align=center>\n";
    $showPollStr .= sprintf("<tr><td colspan=\"4\" class=\"pollTitle\">%s</td></tr>\n",
			    $this->pollTitle);
    for ($i=0;$i<count($this->polldata); $i++) {

      $percent = ($this->totalVotes != 0)?
	(100 / $this->totalVotes * $this->polldata[$i]["counter"]):
	0;
      
      $showPollStr .= sprintf(" <tr> \n".
	     "  <td class=\"pollItem\">%s</td>\n".
	     "  <td class=\"pollImage\"><img src=\"%s\" width=%d height=%d></td>\n".
	     "  <td class=\"pollPercent\">%d %s</td>\n".
	     "  <td class=\"pollVotes\">%d</td>\n".
	     " </tr>\n",
	     $this->polldata[$i]["item"],
	     $this->pollImage,
	     round($percent*$this->pollImageScale),
	     $this->pollImageHeight,
	     round($percent),
	     "Prozent",
	     $this->polldata[$i]["counter"]);
    }
    $showPollStr .= sprintf(" <tr>\n".
			    "  <td class=\"pollSummary\" colspan=\"4\">%s %s</td>\n" .
			    " </tr>\n",
			    $this->pollSummaryText,
			    $this->totalVotes);
    $showPollStr .= "</table>\n";
    return $showPollStr;
  }

  function getMaxReachedMessage_() {
    $mesgMaxReached = sprintf("<table class=\"maxReachedTable\" align=center>\n".
			      "<tr>\n".
			      " <td class=\"maxReachedMessage\">%s</td>\n" .
			      "</tr>\n</table>\n",
			      $this->messageMaxReached);
    return $mesgMaxReached;
  }

  function maxReachedAction_($vote) {
	// insert here whatever you want to do when maxpoll is
	// reached, for example send an email or pop up a window
	// or something else
  }

}

class DBHTMLActionPoll extends HTMLActionPoll {

  var $dbPoll;

  function DBHTMLActionPoll($dbPoll) {
    $this->dbPoll = $dbPoll;
    $this->HTMLActionPoll($dbPoll);
  }

  // we have to overwrite the writePoll_ Method, since now
  // there is a convenient way to update our counter in the
  // database and to add the ip information via sql. 
  function writePoll_($vote) {
    $this->dbPoll->riseCounter($vote);    
    $this->dbPoll->writeIP($vote,$this->caller);
  }
}

// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
// --------------------- end of class definitions ------------------------
// -----------------------------------------------------------------------

?>

Return current item: Actionpoll