0

I have implemented a system where people can report from when to when they have visited a customer, and what they have done there. Now i want to add a function that lets the customers sign the specified service. They can rewiew the reported data, and under this overview i have implemented an HTML5 canvas with signature_pad (https://github.com/szimek/signature_pad), so they can accept the data.

Under the signature pad there are two buttons. One to clear the signature, and one to save the signature.

What i want to implement now is, that when you click the SAVE button, the content of the canvas is stored as a file on the website, after a fresh signature ID has been pulled from the database, and then the user is forwarded to the page with the overview over his reports.

I am handling all database operations in a central handlers.php file, that is loaded with the base system.php framework, and checks for required activities with "if (isset($_POST['NameOfTheFunction']))".

A little background to how the website works:
Overview of the filesystem:
.\system.php <- provides the framework with database connection, languaegesettings, and loads all content
.\content\addsignature.php <- is one content that can be loaded. If provided an existing report-id shows a signature form to sign a service
.\content\handlers.php <- Is loaded by system.php and "listens" for actions it should take
.\js\signature.js <- Is supposed to handle for example the clicking of the save button

Here's the part that created the canvas (addsignature.php):

echo "
<div class=\"row vdivide\">
    <div class=\"col-sm-2 text-center\"><input type=\"hidden\" name=\"rid\" id=\"rid\" value=\"".$_GET['rid']."\"></div>
    <div class=\"col-sm-8 text-center\">
        <div id=\"signature-pad\" class=\"signature-pad\">
            <div class=\"signature-pad--body\">
                <canvas></canvas>
            </div>
        </div>
    </div>
    <div class=\"col-sm-2 text-center\"></div>
</div>
<div class=\"row vdivide\">
    <div class=\"col-sm-2 text-center\"></div>
    <div class=\"col-sm-4 text-center\">
        <div class=\"btn-group\">
            <button type=\"button\" class=\"btn btn-primary\" aria-haspopup=\"true\" aria-expanded=\"false\" data-action=\"clear\">".$clear."</button>
        </div>
    </div>
    <div class=\"col-sm-4 text-center\">
        <div class=\"btn-group\">
            <button type=\"button\" class=\"btn btn-primary\" aria-haspopup=\"true\" aria-expanded=\"false\" data-action=\"save\">".$save."</button>
        </div>
    </div>
    <div class=\"col-sm-2 text-center\"></div>
</div>
<script src=\"./js/signature_pad.umd.js?v=".time()."\"></script>
<script src=\"./js/signature.js?v=".time()."\"></script>
";


And here is the relevant part of the signature.js to save the file:

var saveButton = document.querySelector("[data-action=save]");
    saveButton.addEventListener("click", function (event) {
  if (signaturePad.isEmpty()) {
    alert("Please provide a signature first.");
  } else {
    var dataURL = signaturePad.toDataURL("image/jpeg");
    //alert("RID: " + rid + "DataURL:" + dataURL);
    $.ajax({
      type: "POST",
      url: "../system.php",
      data: {
         imgBase64: dataURL,
         rid: rid,
         SaveSignature: true
      }
    });
  }
});


And here is the content of the handlers.php file:

if (isset($_POST['SaveSignature'])) {
    $query = "INSERT INTO signatures (SIG_RID) VALUES ('".$_POST['rid']."')";
    try {
        $statement = $dbc->prepare($query);
        $statement->execute();
        $message = "<div class=\"alert alert-success alert-dismissible\">
<a href=\"#\" class=\"close\" data-dismiss=\"alert\" aria-label=\"close\">&times;</a>
    ".$signaturesavesuccess."
</div>";
    }
    catch (PDOException $e) {
       $message = "<div class=\"alert alert-danger alert-dismissible\">
<a href=\"#\" class=\"close\" data-dismiss=\"alert\" aria-label=\"close\">&times;</a>
    ".$signaturesavefailure."
</div>";
    }

    $query = "SELECT SIG_ID FROM signatures WHERE SIG_RID = '".$_POST['rid']."'";
    foreach ($dbc->query($query) as $row) {
        $sigid = $row['SIG_ID'];
    }

    $query = "UPDATE reports SET R_Signature = '".$sigid."' WHERE R_ID = '".$_POST['rid']."'";
    try {
        $statement = $dbc->prepare($query);
        $statement->execute();
        $message = "<div class=\"alert alert-success alert-dismissible\">
<a href=\"#\" class=\"close\" data-dismiss=\"alert\" aria-label=\"close\">&times;</a>
    ".$signaturesavesuccess."
</div>";
    }
    catch (PDOException $e) {
       $message = "<div class=\"alert alert-danger alert-dismissible\">
<a href=\"#\" class=\"close\" data-dismiss=\"alert\" aria-label=\"close\">&times;</a>
    ".$signaturesavefailure."
</div>";
    }

    define('UPLOAD_DIR', 'signatures/');
    $img = $_POST['imgBase64'];
    $img = str_replace('data:image/png;base64,', '', $img);
    $img = str_replace(' ', '+', $img);
    $data = base64_decode($img);
    $file = UPLOAD_DIR . $sigid . '.jpg';
    $success = file_put_contents($file, $data);
    print $success ? $file : 'Unable to save the file.';

}

So what i want is the whole "SaveSignature"-part of the handlers.php called, the image saved to the specified location, and the user forwarded to the page "system.php?site=myreports".

I hope anyone here can help me with that. I have no idea what could be wrong.

  • 1
    So, other than where you're requesting an `image/jpeg` from your canvas and you're stripping `image/png` from the posted values and saving it as a `.png` file, what exactly are you having trouble with? – rickdenhaan Dec 25 '18 at 13:34
  • Thank you, i have fixed that now. My 2 problems seem to be that: 1. handlers.php or the function within isn't called at all (nothing is done in the database...) 2. I don't know how to forward to another page after the POST is done. – Marcel Lehmann Dec 25 '18 at 14:44
  • I have been fiddling around, and i have solved the problem with the handlers.php untouched by calling system.php and not handlers.php. handlers.php was missing some context that only system.php could give. Now the problem that remains that the pictures saved to the filesystem are unusable. There must be a problem with the grabbing and saving of the image. I have updated the code above. – Marcel Lehmann Dec 25 '18 at 15:58
  • *"the pictures saved to the filesystem are unusable"* -- in what way? Is there actually anything in the files or is their size 0 bytes? If you open one of the files in a text editor, does it look like gibberish (raw binary data with all kinds of funky characters) or is it still a base64 string beginning with `"data:"`? If it's binary data, is it JPEG (you should see `"JFIF"` somewhere in the first couple of bytes) or PNG (you should see `"PNG"` somewhere in the first couple of bytes)? – rickdenhaan Dec 25 '18 at 16:22
  • As for problem 2 (redirecting after the POST), you can add a `success` and `error` handler to your `$.ajax()` call to do something after the POST request is finished. `success` will fire if the server responds properly, `error` if there's some kind of error (like a 404 not found, 500 internal server error, etc.) -- very useful for debugging – rickdenhaan Dec 25 '18 at 16:24
  • I have fixed the defect images with this: https://stackoverflow.com/questions/1532993/i-have-a-base64-encoded-png-how-do-i-write-the-image-to-a-file-in-php Now my only remaining topic is the redirection. It's a good idea to implement this via success and error, thanks a lot! But how exactly do i redirect with JavaScript? I've searched for it but didn't find what i was looking for... – Marcel Lehmann Dec 25 '18 at 17:03
  • `window.location.href = '/other_page';` – rickdenhaan Dec 25 '18 at 17:23
  • Thanks a lot. Everything works as it should now. You have been a great help!!! – Marcel Lehmann Dec 26 '18 at 11:25

0 Answers0