1

I'm attempting to build a simple PHP voting system where a website user is asked to vote on their favorite photo. Only one vote is permitted each day.

When a vote is cast the PHP script will:

====

1 -- checks the users IP address and compares it to the IP Log text file

2 -- if the users IP address is found in the log it checks to see if the last vote (for that IP address) was submitted on the current date

3 -- If the users IP address was logged and the last vote was on the current date the user is redirected to page reminding them only one vote is allowed per day

4 -- If the users IP address was logged but the last vote was prior to the current date, the vote is recorded and the user is redirected to a thank you for voting page

5 -- If the user IP address is not logged the vote is recorded and the user is redirected to a thank you for voting page.

====

Unfortunately the PHP script I'm working with will do 1 of 2 things:

1 -- If a "break" is included after the if/else statement ($logIP == $ipAddress), the script adds two votes and two IP entries into the log

2 -- If the "break" is removed, one vote is entered and one IP address is recorded. However, regardless of the vote and IP being recorded, new voters and returning votes are redirected to the page reminding them only one vote is permitted each day by the same user

The script is as follows:

====

// GET USERS VOTE, IP ADDRESS AND TODAYS DATE
$userVote = $_REQUEST['vote'];
$ipAddress = $_SERVER["REMOTE_ADDR"];
$ipDate = date("Y/m/d");
// IF THE USERS VOTE IS NULL, REDIRECT TO ERROR PAGE
if ($userVote != "") {
    $userFound = false;
    $userVoted = false;
    echo $userFound . " -- " . $userVoted . "<br /><br />";
    $file_handle = fopen("ip_log.txt", "r");
    // LOOP THROUGH FILE IP ADDRRESSES AND DATES THOSE ADDRESSES WHERE LOGGED
    while (!feof($file_handle)) {
        $line_of_text = fgets($file_handle);
        $parts = explode('||', $line_of_text);
        $logIP = $parts[0];
        $logDate = $parts[1];
        // CHECK IF THE LOGGED IP ADDRESS MATCHES THE USERS IP ADDRESS
        if ($logIP == $ipAddress) {
            $userFound = true;
            // CHECK IF THE LOGGED VOTE DATE MATCHES == TODAY FOR THE CURRENT IP ADDRESS BEING CHECKED
            if ($logDate == $ipDate) {
                // IP ADDRESS FOUND AND LOGGED DATE == TODAY, RREDIRECT USER TO TRY AGAIN LATER PAGE
                header("Location: http://www.fotohuis.ca/vote/tryagain.html");
                exit;
            }
            else {
                // IP ADDRESS FOUND BUT LOGGED DATE != TODAY, KEEP CHECKING UNTIL EOF
            }
        }
        else {
            // IP ADDRESS NOT FOUND, KEEP CHECKING UNTIL EOF
            continue;
        }
    }
    // USER FOUND
    if ($userFound == true) {
        // USER FOUND BUT THE LOGGED VOTE DATE != TODAY
        if ($userVoted == false) {
            // GET IP ADDRESS LOG CONTENT
            $filename1 = "ip_log.txt";
            $content1 = file($filename1);
            // INSERT USER IP ADDRESS INTO LOG
            $insertip = "\r\n" . $ipAddress . "||" . $ipDate;
            $fp1 = fopen($filename1, "a");
            fputs($fp1, $insertip);
            fclose($fp1);
            // GET POLL RESULT CONTENT
            $filename2 = "poll_result.txt";
            $content = file($filename2);
            // PUT VOTE CONTENT INTO ARRAY
            $array = explode("||", $content[0]);
            $picOne = $array[0];
            $picTwo = $array[1];
            $picThree = $array[2];
            $picFour = $array[3];
            $picFive = $array[4];
            $picSix = $array[5];
            // CALCULATE VOTE TOTAL
            if ($userVote == 0) {
                $picOne = $picOne + 1;
            }
            if ($userVote == 1) {
                $picTwo = $picTwo + 1;
            }
            if ($userVote == 2) {
                $picThree = $picThree + 1;
            }
            if ($userVote == 3) {
                $picFour = $picFour + 1;
            }
            if ($userVote == 4) {
                $picFive = $picFive + 1;
            }
            if ($userVote == 5) {
                $picSix = $picSix + 1;
            }
            // INSERT USER VOTE
            $insertvote = $picOne . "||" . $picTwo . "||" . $picThree . "||" . $picFour . "||" . $picFive . "||" . $picSix;
            $fp2 = fopen($filename2, "w");
            fputs($fp2, $insertvote);
            fclose($fp2);
            // /REDIRECT USER TO THANK YOU FOR VOTING PAGE
            header("Location: http://www.fotohuis.ca/vote/thankyou.html");
            exit;
        }
        // USER FOUND AND THE LOGGED VOTE DATE == TODAY
        else {
            // USER ATTEMPTED TO VOTE 2+ TIMES IN THE SAME DAY, REDIRECT USER TO TRY AGAIN LATER PAGE
            header("Location: http://www.fotohuis.ca/vote/tryagain.html");
            exit;
        }
    }
    // USER NOT FOUND
    else {
        // GET IP ADDRESS LOG CONTENT
        $filename1 = "ip_log.txt";
        $content1 = file($filename1);
        // INSERT USER IP ADDRESS INTO LOG
        $insertip = "\r\n" . $ipAddress . "||" . $ipDate;
        $fp1 = fopen($filename1, "a");
        fputs($fp1, $insertip);
        fclose($fp1);
        // GET POLL RESULT CONTENT
        $filename2 = "poll_result.txt";
        $content2 = file($filename2);
        // PUT VOTE COUNT INTO ARRAY
        $array = explode("||", $content2[0]);
        $picOne = $array[0];
        $picTwo = $array[1];
        $picThree = $array[2];
        $picFour = $array[3];
        $picFive = $array[4];
        $picSix = $array[5];
        // CALCULATE VOTE TOTAL
        if ($userVote == 0) {
            $picOne = $picOne + 1;
        }
        if ($userVote == 1) {
            $picTwo = $picTwo + 1;
        }
        if ($userVote == 2) {
            $picThree = $picThree + 1;
        }
        if ($userVote == 3) {
            $picFour = $picFour + 1;
        }
        if ($userVote == 4) {
            $picFive = $picFive + 1;
        }
        if ($userVote == 5) {
            $picSix = $picSix + 1;
        }
        // INSERT USER VOTE
        $insertvote = $picOne . "||" . $picTwo . "||" . $picThree . "||" . $picFour . "||" . $picFive . "||" . $picSix;
        $fp2 = fopen($filename2, "w");
        fputs($fp2, $insertvote);
        fclose($fp2);
        // REDIRECT USER TO THANK YOU FOR VOTING PAGE
        header("Location: http://www.fotohuis.ca/vote/thankyou.html");
        exit;
    }
    fclose($file_handle);
}

====

Any help with this will be greatly appreciated as I've been at it for a week now with no progress :(

jlocker
  • 1,478
  • 1
  • 12
  • 23
Mike C
  • 11
  • 1

1 Answers1

0

This code can be greatly simplified to make it easier to understand and modify in the future. There is also some repeated code that doesn't need to be.

This is untested but it should work and give you an idea on how to move forward.

Before you try it make sure to test it or backup your existing vote counts!!!

<?php

$userVote = $_REQUEST['vote'];
$ipAddress = $_SERVER["REMOTE_ADDR"];
$ipDate = date("Y/m/d");
$ipLogFile = 'ip_log.txt';
$resultLogFile = 'poll_result.txt';

//IF THE USERS VOTE IS NULL or out of range, REDIRECT TO ERROR PAGE
if (empty($userVote) || $userVote < 0 || $userVote > 5) {
    header('Location: errorpage.html');
    exit;
}

$file_handle = fopen($ipLogFile, "r");

//LOOP THROUGH FILE IP ADDRRESSES AND DATES THOSE ADDRESSES WHERE LOGGED        
while (!feof($file_handle) )
{
    $line_of_text = fgets($file_handle);
    $parts = explode('||', $line_of_text);
    $logIP = $parts[0];
    $logDate = $parts[1];

    if ($logIP == $ipAddress && $logDate == $ipDate) {
        // IP ADDRESS FOUND AND LOGGED DATE == TODAY FOR CURRENT IP
        header("Location: http://www.fotohuis.ca/vote/tryagain.html");
        exit;
    }
}
fclose($file_handle);

// user has not voted ever, or today

$insertip = "\r\n".$ipAddress."||".$ipDate;
file_put_contents($ipLogFile, $insertip, FILE_APPEND);

//GET POLL RESULT CONTENT
$fp = fopen($resultLogFile, 'r+'); // open for reading and writing
flock($fp, LOCK_EX);  // lock file so it can't be changed
$content = fgets($fp); // read contents of file

//PUT VOTE CONTENT INTO ARRAY
$array = explode("||", $content);
// $array[0] = picOne; $array[1] = picTwo; etc

$array[$userVote] = (int)$array[$userVote] + 1;

ftruncate($fp); // truncate the file so it is empty
rewind($fp); // jump to beginning of file

$insertvote = implode('||', $array); // array to string 0||1||2||3||4||5
fwrite($fp, $insertvote); // write new vote tally

flock($fp, LOCK_UN); // unlock file
fclose($fp); // close file

///REDIRECT USER TO THANK YOU FOR VOTING PAGE
header("Location: http://www.fotohuis.ca/vote/thankyou.html");
exit;

Hope that helps!

drew010
  • 68,777
  • 11
  • 134
  • 162
  • Thanks for cleaning up the code... makes it much easier to read. Two things I noticed after testing: (1) votes are only added to the second position of the array, and (2) the same error occurs; specifically the user submits a vote, the while loop runs, doesn't find the IP/date, ads the IP/date, then its as if the while loop runs again and now finds the IP/date and redirects the user to the already voted page (this despite not having previously voted.) --- once a vote is accepted the user should get redirected to the thank you page. Thoughts? – Mike C Oct 01 '15 at 20:46
  • There was an error with the `$array = explode("||", $content[0]);` line which is now corrected in the answer. The loop only runs once so I'm not sure why it would do what you indicated unless you have more code that isn't shown here. – drew010 Oct 05 '15 at 16:50
  • Yeah... I was toying around with the code and just figured that out. Still having the issue where the user who casts a vote for the first time (or first time in a day) is forwarded to the "tryagain.html" page ... it's as if the redirect to the "thankyou.html" page doesn't get processed!?! – Mike C Oct 08 '15 at 23:32