2

I'm trying to send an email with an image attachment. I'm able to send the email,but I have no success with displaying the picture, its just black. The php is receiving a base64 string that it is an image. Also I want to do it without storing anything or writing anything on the server. Is there a possible way to do this?
This is what the php looks like.

   <?php 
    $base64 = $_POST['dataURL'];
    //define the receiver of the email 
    $to = 'some@mail.com'; 
    //define the subject of the email 
    $subject = 'Test email with attachment'; 
    //create a boundary string. It must be unique 
    //so we use the MD5 algorithm to generate a random hash 
    $random_hash = md5(date('r', time())); 
    //define the headers we want passed. Note that they are separated with \r\n 
    $headers = "From:Francisco Granado\r\nReply-To: webmaster@example.com"; 
    //add boundary string and mime type specification 
    $headers .= "\r\nContent-Type: multipart/mixed; boundary=\"PHP-mixed-".$random_hash."\""; 
    //read the atachment file contents into a string,
    //encode it with MIME base64,
    //and split it into smaller chunks
    $attachment = base64_decode($base64); 
    //define the body of the message. 
    ob_start(); //Turn on output buffering 
    ?> 
    --PHP-mixed-<?php echo $random_hash; ?>  
    Content-Type: multipart/alternative; boundary="PHP-alt-<?php echo $random_hash; ?>" 

    --PHP-alt-<?php echo $random_hash; ?>  
    Content-Type: text/plain; charset="iso-8859-1" 
    Content-Transfer-Encoding: 7bit

    This email have attached a image file 
    For SED_WE analysis purposes. 

    --PHP-alt-<?php echo $random_hash; ?>  
    Content-Type: text/html; charset="iso-8859-1" 
    Content-Transfer-Encoding: 7bit

    <h1>SED_WE</h1>
    <p>This email have attached a image file </p> 
    <p>For SED_WE analysis purposes.</p> 

    --PHP-alt-<?php echo $random_hash; ?>-- 

    --PHP-mixed-<?php echo $random_hash; ?>  
    Content-Type: image/jpeg; name="attachment.jpeg"  
    Content-Transfer-Encoding: base64  
    Content-Disposition: attachment  

    <?php echo $attachment; ?> 
    --PHP-mixed-<?php echo $random_hash; ?>-- 

    <?php 
    //copy current buffer contents into $message variable and delete current output buffer 
    $message = ob_get_clean(); 
    //send the email 
    $mail_sent = @mail( $to, $subject, $message, $headers ); 
    //if the message is sent successfully print "Mail sent". Otherwise print "Mail failed" 
    echo $mail_sent ? "Mail sent" : "Mail failed"; 
   ?>

Also here is my js:

$(document).ready(function (e) {
    var imgBase64;
    function imgToBase64(url, callback, outputFormat) {
        var canvas = document.createElement('CANVAS'); //Creates variable containing canvas in the DOM
        var canvas_context = canvas.getContext('2d'); //Creates canvas environment (context) in 2 dimensions 
        var img = new Image; // new Image instance
        img.crossOrigin = 'Anonymous'; //Cross origin textures from other URL's are permitted (see http://blog.chromium.org/2011/07/using-cross-domain-images-in-webgl-and.html) for more information
        console.log('ON LOAD IMG');
        //Image load trigger, encode image into base64
        img.onload = function () {
            //Determine canvas height and width 
            canvas.height = img.height;
            canvas.width = img.width;
            console.log('Canvas info:\n Height: ' + canvas.height + '\n Width: ' + canvas.width);
            //Draws the image raw format 
            canvas_context.drawImage(img, 0, 0);
            var dataURL = canvas.toDataURL(outputFormat || 'image/png'); //THIS IS WHERE THE MAGIC HAPPENS (img encode to base64)
            //imgBase64 = dataURL;
            $('#show-picture').attr('src', dataURL); //Change source of the #show-picture image tag to the base64 string to show preview to user 
            console.log(dataURL);
            callback.call(this, dataURL); //Callback function @param {dataURL} 
            // Clean up
            canvas = null;
        };
        img.src = url;
    }

    //Reads the path to the picture for a preview 
    function readURL(input) {
        if (input.files && input.files[0]) { //if file exist
            var reader = new FileReader(); //new instance of the file reader

            reader.onload = function (e) { //when the reader loads the chosen file...
                imgToBase64(e.target.result, function (dataURL) { //..then the is converted 
                    setDataURL(dataURL);
                });
            }
            reader.readAsDataURL(input.files[0]);
        }
    }

    function setDataURL(dataURL){
        imgBase64 = dataURL;
        console.log('setDataUrl=>'+imgBase64);
    }



    $('#take-picture').change(function () {
        readURL(this);
        console.log('ONLOAD'+imgBase64);
    });

    $('#uploadImgBtn').on('click',function(){
        var base64String= imgBase64.replace(/data:image[^;]+;base64,/,'');
        console.log('base64string'+base64String);
        $.post('php/mailer.php',base64String,function(data){alert('Success!'); console.log('response: '+data)});
    });

});

P.S: I've tried different things from other post, but there's no success or they write on the server, also it's my first time on php so any good suggestion are very welcomed.

Ch32k0
  • 244
  • 3
  • 17

1 Answers1

2

In the javascript file where it sends the data to php there was no key name of dataURL, and I needed to remove the data:image/*;base64, out of the string to send the pure base64. So its suppose to be like this:

$('#uploadImgBtn').on('click',function(){
        var base64String= imgBase64.replace(/data:image[^;]+;base64,/,'');
        console.log('base64string'+base64String);
        $.post('php/mailer.php',{dataURL:base64String},function(data){
            alert('Success!');
            console.log('response: '+data)});
    });

Then the php would receive the dataURL and all I needed to do it was chunk_split that base64 string. Like this:

  $base64 = $_POST['dataURL'];
   ...
  $attachment = chunk_split($base64);

  ...
Ch32k0
  • 244
  • 3
  • 17