0

ive just run into a problem. I am sending mail after the form is submitted. I dont want the mail to be sent more than once so i redirect on the same page with setting $_SESSION that controls it. It all worked fine but there is still one problem. Ive just recently found out, that some users cant wait those 5-10 seconds till the email is sent. They click on X in the web browser (I mean the left top X that you can click on while the page is loading something to stop it) and try to send the form again. And when they do this the mail can be sent more than once, because the redirect is not firing up imidiately, just after the mail is sent. Is there any way to do this in one php file or do i have to redirect on the second php file where the email is sent then?

Here is the code :

session_start();

require_once('conne387s1.php');

$today = date('Y-m-d H:i:s');

if(isset($_SESSION['vozidlo']) && !isset($_SESSION['repeat'])){
    $_SESSION['repeat'] = true;

    $select = "SELECT * FROM vozidla WHERE ID = ".$_SESSION['vozidlo'];
    $vozidlo = mysql_fetch_array(mysql_query($select));

    $spz = $_SESSION['SPZ'];

    $update = "UPDATE vozidla SET SPZ = '".$spz."', CISLO_OSVEDCENIA = '".$_SESSION["CISLO_OSVEDCENIA"]."' WHERE ID = ".$_SESSION['vozidlo'];
    mysql_query($update) or die(mysql_error());

//    $update = "UPDATE zmluvy SET DOHLASIL_SPZ = '".$today."' WHERE CHECK_ID = '".$_SESSION['chid']."'";
//    mysql_query($update) or die(mysql_error());

    $select = "SELECT * FROM zmluvy WHERE CHECK_ID = '".$_SESSION['chid']."'";
    $zmluva = mysql_fetch_array(mysql_query($select));

    $dotaz = "SELECT * FROM `poistnici` WHERE `ID` = ".$zmluva["DRZITEL"];
    $vysl = MySQL_Query($dotaz);
    $drzitel = mysql_fetch_array($vysl);

    $natypoval = '';
    if (isset($_SESSION["pred_ID7425"])){
        $natypoval = $_SESSION["pred_ID7425"];
    } else {
        //test ci je to zdielany klient
        if (!empty($_SERVER['HTTP_CLIENT_IP'])){
          $natypoval=$_SERVER['HTTP_CLIENT_IP'];
        //je to proxy adresa
        }elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])){
          $natypoval=$_SERVER['HTTP_X_FORWARDED_FOR'];
        }else{
          $natypoval=$_SERVER['REMOTE_ADDR'];
        }
        // prehodenie na int z IP
        $natypoval = ip2long($natypoval);
    }

    $spz_zmena = false;
    if($vozidlo['SPZ'] != $spz){
        $spz_zmena = true;
        $insert = "INSERT INTO `kasko_zmluvy_zmeny` (`ID_ZML`,`TIME`,`VYKONAL`,`ZMENA`,`PZP`)
                   VALUES(".$zmluva["ID"].",'".date('Y-m-d H:i:s', time())."',".$natypoval.",'".mysql_real_escape_string('Zmena EČV '.$vozidlo['SPZ'].'->'.$spz)."',1)"; // vykonal - 0 - system rychlepoistneie s.r.o
        MySQL_Query($insert) or die(mysql_error());
    }

    if($vozidlo['CISLO_OSVEDCENIA'] != $_SESSION['CISLO_OSVEDCENIA']){
        $insert = "INSERT INTO `kasko_zmluvy_zmeny` (`ID_ZML`,`TIME`,`VYKONAL`,`ZMENA`,`PZP`)
                   VALUES(".$zmluva["ID"].",'".date('Y-m-d H:i:s', time())."',".$natypoval.",'".mysql_real_escape_string('Zmena čísla TP '.$vozidlo['CISLO_OSVEDCENIA'].'->'.$_SESSION['CISLO_OSVEDCENIA'])."',1)"; // vykonal - 0 - system rychlepoistneie s.r.o
        MySQL_Query($insert) or die(mysql_error());
    }

    $id_zmluva = $zmluva['ID'];
    $id_insur = $zmluva['POISTOVNA'];
    $path = getcwd();
    $file_name_bk = $path."/predajca/output/temp/Biela_karta_".$zmluva["CISLO_ZMLUVY"];
    $file_name2 = $file_name_bk;
    $vystup = 'F';
    $dohlasovanie = true;


    require_once("fpdf/fpdf.php"); 
    require_once("fpdi/fpdi.php");
    if($zmluva['POISTOVNA'] == 23){
      require("biela_karta_genertel.php");
    } else {
      require("biela_karta.php");
    }

    if (isset($_SESSION["pred_ID7425"])){
        $vykonal = $_SESSION["pred_ID7425"];
    } else {
        //test ci je to zdielany klient
        if (!empty($_SERVER['HTTP_CLIENT_IP'])){
          $vykonal=$_SERVER['HTTP_CLIENT_IP'];
        //je to proxy adresa
        }elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])){
          $vykonal=$_SERVER['HTTP_X_FORWARDED_FOR'];
        }else{
          $vykonal=$_SERVER['REMOTE_ADDR'];
        }
        // prehodenie na int z IP
        $vykonal = ip2long($vykonal);
    }

    require_once("mail/class.phpmailer.php");
    require_once("sendMailServer.php");
    require_once('../temp_output/crn/reminder_povinne.php');

    $mass_mail = new reminder_povinne(6);
    $mass_mail->sendBielaKarta(mysql_query($select),$file_name_bk.".pdf", $vykonal);

    if($zmluva['EXPORT'] != NULL && $zmluva['EXPORT'] != '000-00-00 00:00:00'){
        $mass_mail = new reminder_povinne(7);
        $mass_mail->sendDoplneniePoistovna(mysql_query($select),$spz_zmena);
    }

    session_destroy();
    require_once("env1.html");
    require_once("env1_1.html");
    require_once("env2.html");

    echo '</div><div class="article-content"><h1>Ďakujeme za doplnenie údajov k zmluve.</h1><h2> Na Váš e-mail bolo zaslané nové potvrdenie o poistení (biela karta) s doplnenými údajmi.</h2></div>';

    require_once("env3.html");
    require_once("env4.html");
}

if(isset($_POST['psc']) && !empty($_POST['psc'])){
    $_POST['comp60'] = preg_replace("/[^A-Za-z0-9]/", '', $_POST['comp60']);

    $err = array();

    if (strlen($_POST["comp60"]) == 0)
        $err[] = "60|"."„EČV nemôže byť prázdne. Pokiaľ EČV nie je pridelené, alebo sa bude meniť, zvoľte možnosť „zatiaľ nepridelené/EČV sa bude meniť.“";
    else if (strlen($_POST["comp60"]) != 5 && strlen($_POST["comp60"]) != 0)
        $err[] = "60|"."Nesprávny formát ŠPZ (XX000XX)";
    if (strlen($_POST["comp61"]) != 8) $err[] = "61|"."Nesprávne zadaný údaj séria a číslo Osvedčenia o evidencii vozidla.";

    $spz = $_POST['psc'].$_POST['comp60'];

    $_SESSION['SPZ'] = $spz;
    $_SESSION['CISLO_OSVEDCENIA'] = $_POST["comp61"];

    if (count($err) < 1){
        $_SESSION['vozidlo'] = $_POST['vozidlo'];
        $_SESSION['chid'] = $_POST['chid'];
        header('Location: dohlasit_spz.php');
//        header('Location: kone.php');
        return;
    }

} 

As i said the problem is that the redirection fires up after the email is sent and i dont know why. Please help me I am really desperate.

EDIT: I need to redirect onto the same page and then execute the mail function. Otherwise the client has time to click on the X on web browser (I mean the left top X that you can click on while the page is loading something to stop it) and resend the form. Is there any way to do this in one php file? Because as it is now the mail function fires first ...

Redrif
  • 650
  • 4
  • 22

3 Answers3

1

You can call session_write_close(), before calling the mailer function, this will persist the session right away instead of doing it at the end of the script. Beware that this also ends the session, so usages of $_SESSION after calling this function are not recommended.

If you need to use the session after the mail sending, you can reopen the session after the email has been sent, details of how this can be found in this SO question: Reopening a session in PHP.

You will also need to add an email was sent flag, in order for the second request to know about the progress of the email operation and to redirect if the email was sent by the previous request.

You will also need to enable the ignore_user_abort php.ini setting.

The flow should be as following:

  1. check if the email in progress flag is set in session, if yes ask the user to retry in a couple of seconds
  2. check if the email was sent flag, if yes redirect the user and exit
  3. save the email in progress flag in session
  4. call session_write_close()
  5. send the email
  6. reopen the session
  7. set the email was sent flag
  8. continue with the rest of the script
  9. make sure the page where the user is redirected clears the two flags, otherwise further submits of the form (with other data) will not properly work
Community
  • 1
  • 1
Cristik
  • 30,989
  • 25
  • 91
  • 127
  • So can you please point me where should i put that session_write_close(); to get it done? – Redrif Apr 20 '15 at 08:54
  • Because i need the session in order to send the mail you know. I cant close the session right before the redirection because i need to access the session after the redirection. – Redrif Apr 20 '15 at 08:57
  • Its not gonna work since i got the $_SESSION in if statement. If i put into that part of script session_write_close(); it just redirects me to the same page but the $_SESSION will no longer be set so even if i copy the $_SESSION into variable it will not work. I tried it and its not working. Do you have any other idea? Or am I missing something? – Redrif Apr 20 '15 at 09:21
  • Move what to the end of a page? The mail execution? If i do that it will again not redirect and first execute the mail and then redirect. That is the whole problem. I cant give enough time for the user to click on X in web browser and click on the submit button again. So it has to redirect first and then send the mail. – Redrif Apr 20 '15 at 09:28
  • I tried it and as soon as i reopen the session it again redirects after the executing the email and not before ... Seems like it cannot be done in one php file. I tried it now like 20 times on 20 different places in script where i thought it should finally work but it doesnt ... I dont get it why it doesnt first redirect and then execute the mail. – Redrif Apr 20 '15 at 10:31
  • No haha didnt wrote it clearly enough. That X doesnt mean to close the web browser, it means that X that stops the processing of the page you know? When some page is loading too long you can click on that X and cancel the process of loading. That is the X i am talking about the whole time. Now you understand where is the problem? :-) I am gonna edit my question to make it more clear. My bad, im really sorry – Redrif Apr 20 '15 at 11:24
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/75707/discussion-between-redrif-and-cristik). – Redrif Apr 20 '15 at 11:27
  • Hi @Cristik I wanted you to know that i used jquery ajax using the same file to process it. When the client clicked on submit button it went to disabled state and when he tried to reload it wouldnt let him since the mail was still sending. He couldnt click on the X the whole time since the form was sent through ajax thus solving the whole problem. Thank you for your time here and since your answer didnt help me 100% i wont check it as right, but i will sure upvote you for the effort :-) – Redrif Apr 22 '15 at 23:22
0

The best approach will be to redirect the user to another page e.g. thankyou.php with an appropriate message.

Alternatively, you can show the loader till the mail is not sent and then redirect the user to the page as you are currently doing.

Hope this helps.

Thanks Anurag

Anurag
  • 469
  • 3
  • 5
  • Thank you for your answer, but i want to figure out if there is any other way than redirecting to the other php file where i execute the code that sends the mail. And loader wont help because even if 99 percent of users would get it, that the application is processing, the one percent of the users could still resend it when they click on X on browser. – Redrif Apr 20 '15 at 08:59
0

I would create a separate script with whatever code is taking a while to complete. I'd then call that script after the user submits the form, and redirect the user to a page indicating that the process should be complete soon.

Execute the script like so to allow it to run in the background:

exec("php /path/to/script.php > /dev/null &", $output)
  • Hi there, as i said i would like to find a way to process it without redirecting into another php file. I could redirect to another php file and then process sending the mail whole time. What Im asking is, if there is some possibility to do it in one php file. – Redrif Apr 20 '15 at 09:24