/portal/class_modul_votings_portal.php
The structure of the portal-class is quite similar to the structure of the admin-class, so we'll only take a look a the portal-specifics.
[ ... ]
parent::__construct($arrModule, $arrElementData);
// save a cookie to store the voting
$objCookie = new class_cookie();
$this->arrCookieValues = explode(",", $objCookie->getCookie($this->STR_COOKIE_NAME));
}
Based on the requirements, the module should save a protocol of votings performed using a cookie. Since the cookie is used at various places in the class, the value is being saved as a class-variable.
public function action() [...]
Controls the behavior of the class. The work is done in actionList() instead.
public function actionList() {
$strReturn = "";
//load the associated voting
$objVoting = new class_modul_votings_voting($this->arrElementData["char1"]);
//view-permissions given?
if($objVoting->rightView()) {
$strVotingContent = "";
if($this->arrElementData["int1"] == 0) {
This is the switch between the two modes: 0 is the voting whereas 1 is a rendering of the results.
//voting mode
//permissions sufficient?
if($objVoting->rightRight1()) {
//check the start n end dates
$objDateStart = null;
$objDateEnd = null;
if($objVoting->getLongDateStart() != "" && $objVoting->getLongDateStart() != 0)
$objDateStart = new class_date($objVoting->getLongDateStart() );
if($objVoting->getLongDateEnd() != "" && $objVoting->getLongDateEnd() != 0)
$objDateEnd = new class_date($objVoting->getLongDateEnd() );
$bitDatesAllow = true;
if($objDateStart != null && $objDateStart->getLongTimestamp() > class_date::getCurrentTimestamp())
$bitDatesAllow = false;
if($objDateEnd != null && $objDateEnd->getLongTimestamp() < class_date::getCurrentTimestamp())
$bitDatesAllow = false;
//already voted before?
if(in_array($objVoting->getSystemid(), $this->arrCookieValues)) {
$strVotingContent = $this->getText("error_voted");
}
else if(!$bitDatesAllow ) {
$strVotingContent = $this->getText("error_dates");
}
else {
In order to be able to vote, the user has to fulfill the conditions tested above: the voting wasn't submitted before, the permission “right1” is given and the start- and end-dates are matching (if given).
$strAnswers = "";
$strAnswerTemplateID = $strListTemplateID = $this->objTemplate->readTemplate("/modul_votings/".$this->arrElementData["char2"], "voting_voting_option");
//load the list of answers
$arrAnswers = $objVoting->getAllAnswers(true);
foreach($arrAnswers as $objOneAnswer) {
$arrTemplate = array();
$arrTemplate["voting_systemid"] = $objVoting->getSystemid();
$arrTemplate["answer_systemid"] = $objOneAnswer->getSystemid();
$arrTemplate["answer_text"] = $objOneAnswer->getStrText();
$strAnswers .= $this->fillTemplate($arrTemplate, $strAnswerTemplateID);
}
Every answer is rendered using the template-section „voting_voting_option“. This provides the most flexibility when layouting the voting. The placeholders available at the template-section are collected in the array $arrTemplate.
//create the wrapper
$strFormTemplateID = $strListTemplateID = $this->objTemplate->readTemplate("/modul_votings/".$this->arrElementData["char2"], "voting_voting");
$arrTemplate = array();
$arrTemplate["voting_answers"] = $strAnswers;
$arrTemplate["voting_systemid"] = $objVoting->getSystemid();
$arrTemplate["voting_action"] = getLinkPortalHref($this->getPagename(), "", "submitVoting");
$strVotingContent .= $this->fillTemplate($arrTemplate, $strFormTemplateID);
The collected and rendered answers are now rendered inside the wrapper „voting_voting“, building the surrounding form.
}
}
else
$strVotingContent = $this->getText("error_permissions");
}
else if($this->arrElementData["int1"] == 1) {
//result mode
$strAnswers = "";
$intTotalVotes = 0;
$strAnswerTemplateID = $strListTemplateID = $this->objTemplate->readTemplate("/modul_votings/".$this->arrElementData["char2"], "voting_result_answer");
//load the list of answers
$arrAnswers = $objVoting->getAllAnswers(true);
//first run to sum up
foreach($arrAnswers as $objOneAnswer) {
$intTotalVotes += $objOneAnswer->getIntHits();
}
foreach($arrAnswers as /** @var class_modul_votings_answer */$objOneAnswer) {
$arrTemplate = array();
$arrTemplate["answer_text"] = $objOneAnswer->getStrText();
$arrTemplate["answer_hits"] = $objOneAnswer->getIntHits();
$arrTemplate["answer_percent"] = "0";
if($objOneAnswer->getIntHits() > 0) { $arrTemplate["answer_percent"] = (int)(100 / ($intTotalVotes / $objOneAnswer->getIntHits())) ;
}
$strAnswers .= $this->fillTemplate($arrTemplate, $strAnswerTemplateID);
}
$strResultTemplateID = $this->objTemplate->readTemplate("/modul_votings/".$this->arrElementData["char2"], "voting_result");
$arrTemplate = array();
$arrTemplate["voting_answers"] = $strAnswers;
$arrTemplate["voting_hits"] = $intTotalVotes;
$strVotingContent .= $this->fillTemplate($arrTemplate, $strResultTemplateID);
}
The way the results are rendered is the same. Instead of rendering a form, a graphical representation of the results is created. The percental distribution of votes is calculated and available in the template-section via the placeholder „answer_percent“.
[ ... ]
}
The last missing part is the saving of the votes submitted by the user. This is the job of the method actionSubmitVoting().
private function actionSubmitVoting() {
$objVoting = new class_modul_votings_voting($this->arrElementData["char1"]);
// check if the submitted vote matches the current one -> multiple votings per page
if($objVoting->getSystemid() == $this->getParam("systemid")) {
//recheck permissions
if($objVoting->rightRight1() && !in_array($objVoting->getSystemid(), $this->arrCookieValues)) {
//load the submitted answer
$strAnswerID = $this->getParam("voting_".$objVoting->getSystemid());
if(validateSystemid($strAnswerID)) {
$objAnswer = new class_modul_votings_answer($strAnswerID);
$objAnswer->setIntHits($objAnswer->getIntHits()+1);
$objAnswer->updateObjectToDb();
$this->arrCookieValues[] = $objVoting->getSystemid();
$objCookie = new class_cookie();
$objCookie->setCookie($this->STR_COOKIE_NAME, implode(",", $this->arrCookieValues));
}
}
}
}
After validating the submitted id, the matching answer-object is loaded and the number of hits are increased by one. To save the new state, the already known method updateObjectToDb() is called. In addition, the value of the cookie is supplemented by the id of the current voting in order to validate the rating-history afterwards.
/templates/modul_votings/votings.tpl
<voting_wrapper>
<div>
<h3>%%voting_title%%</h3>
%%voting_content%%
</div>
</voting_wrapper>
The section “voting_wrapper” acts as some kind of frame for a single voting, not mattering if it's in voting- or in result-mode. The generated contents are placed inside this wrapper.
<voting_voting>
<form method="post" action="%%voting_action%%" id="voting_%%voting_systemid%%">
<table width="80%">
%%voting_answers%%
</table>
<input type="hidden" name="systemid" value="%%voting_systemid%%" />
<input type="submit" value="%%lang_voting_submit%%" class="button" />
<br />
</form>
</voting_voting>
The voting-form is created using the section “voting_voting”. The single answers are rendered using the section “voting_voting_option” before and are placed within the voting-section. So every answer is rendered in its' own section, afterwards the results are rendered in the form-section.
<voting_voting_option>
<tr>
<td width="25">
<input type="radio" name="voting_%%voting_systemid%%" value="%%answer_systemid%%" id="option_%%answer_systemid%%"/>
</td>
<td align="left">
<label for="option_%%answer_systemid%%">%%answer_text%%</label>
</td>
</tr>
</voting_voting_option>
The rendering of the results is done nearly the same way. As before, every answer is rendered independently including a graphical percentual representation using the section “voting_result_answer”. The generated content is then rendered using the section “voting_result”.
<voting_result>
<table width="80%">
%%voting_answers%%
<tr>
<td colspan="2">%%lang_voting_hits%% %%voting_hits%%</td>
</tr>
</table>
</voting_result>
<voting_result_answer>
<tr>
<td colspan="2">%%answer_text%%</td>
</tr>
<tr>
<td width="80%"><img src="http://www.kajona.de/portal/pics/kajona/icon_progressbar.gif" height="15" width="%%answer_percent%%%" alt="%%answer_percent%%%" /></td>
<td>%%answer_hits%% / %%answer_percent%% %</td>
</tr>
</voting_result_answer>



