2

My php file gets passed image/png data and needs to attach it to an e-mail and send said e-mail.

Here is working code from a test file:

<?php
include("include.php");
$subject = "Laptop Collection " . date("Y");
//create a boundary string
$random_hash = md5(date('r', time()));
//define the headers we want passed
$headers[] = "From: Do Not Reply <email@example.com>";
//add boundary string and mime type specification
$headers[] = "Content-Type: multipart/mixed; boundary=\"PHP-mixed-".$random_hash."\"";
ob_start();
$image = "data:image/png;base64,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";
$imgPng = imageCreateFromPng($image);
imageAlphaBlending($imgPng, true);
imageSaveAlpha($imgPng, true);
header("Content-type: image/png");
imagePng($imgPng); 
$i = ob_get_contents();
$attachment = chunk_split(base64_encode($i));
// clear the buffer, but don't destroy it
ob_clean();
// Define Body
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 is the information for laptop problems.  Your signature is attached to this e-mail.

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

<h2>Hello World!</h2>
<p>This is something with <b>HTML</b> formatting.</p>
<img src="cid:signature.png" />
--PHP-alt-<?php echo $random_hash; ?>--

--PHP-mixed-<?php echo $random_hash; ?> 
Content-Type: application/zip; name="signature.png" 
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();

$mail = new \helpdesk\core\mail("email@example.com", $subject, $message);
$mail->setHeaders($headers);
$mail->send();
unset($mail);
?>

Here is my code from a function in my hd (help desk) object that is being called. It is copied and pasted from test.php. I have even set the the image data to the same string on both and it works great in test.php but fails by sending plaintext of all of the multipart php stuff.

public static function createWorkflowData($signatureData, $signatureImage, $reviewData){
        //print_r($signatureData);
       // print_r($signatureImage);
        //print_r($reviewData);
        //exit;
        $stages = $_SESSION['student']->workflow->getAllStages();
        $updateAssignment = array();
        $assignmentID = "";
        $workflowID = null;
        $mysqli = \helpdesk\db\DB::connect();
        $stmt = $mysqli->prepare("INSERT INTO `check_workflow_data`
        (`workflowID`, `key`, `section`, `questionDate`, `answer`, `checkIn`, `WO`, `internalWO`)
        VALUES  (?,?,?,?,?,?,?,?)");
        foreach( $stages as $stage){
            // Skip main stages
            if($stage->getSection() == "main")
                continue;
            // Create Workflow in DB if it is the 1st one
            if($stage->getAssignmentGroup() != $assignmentID){
                $assignmentID = $stage->getAssignmentGroup();
                $workflowID =  \helpdesk\db\hd::createWorkflow($assignmentID, $signatureData);
            }
            //Create Any WO's
            if($stage->getPreparedWO() != null){
                $stage->setWOID( \helpdesk\db\hd::createWO( $stage->getPreparedWO() ) );
            }
            if($stage->getPreparedInternalWO() != null){
                $stage->setInternalWOID( \helpdesk\db\hd::createInternalWO( $stage->getPreparedInternalWO() ) );
            }
            $key = $stage->getKey();
            $section = $stage->getSection();
            $questionDate = (($stage->getAnswerTime())?$stage->getAnswerTime():time());
            $answer = (($stage->getAnswer())?$stage->getAnswer():"Not Answered");
            $checkIn = (($stage->getAnswerCheckIn()=="true")?1:0);
            $WO = $stage->getWOID();
            $internalWO = $stage->getInternalWOID();
            $stmt->bind_param("issisiss",$workflowID, $key, $section, $questionDate,$answer,$checkIn,$WO,$internalWO);
            $stmt->execute();
            if($stmt->error != ""){
                printf("Error: %s.\n", $stmt->error);
            }

            if(($CheckIn = $stage->getAnswerCheckIn()) != null){
                if($CheckIn == "true"){
                    //echo "Will update ".$assignmentID." by setting ".$stage->getSection()." to 1";
                    $updateAssignment[$assignmentID][$stage->getSection()] = 1;
                }else if($CheckIn == "false"){
                    $updateAssignment[$assignmentID][$stage->getSection()] = 0;
                }
            }
            //Prepare this item for this assignment for turn in
        }
        foreach($updateAssignment as $assignmentID => $assignmentUpdate){
            \helpdesk\db\hd::updateAssignment($assignmentID, $assignmentUpdate);
        }
        $stmt->close();
        $subject = "Laptop Collection " . date("Y");
        //create a boundary string
        $random_hash = md5(date('r', time()));
        //define the headers we want passed
        $headers[] = "From: Do Not Reply <email@example.com>";
        //add boundary string and mime type specification
        $headers[] = "Content-Type: multipart/mixed; boundary=\"PHP-mixed-".$random_hash."\"";
        ob_start();
        $image = $signatureImage;
        $imgPng = imageCreateFromPng($image);
        imageAlphaBlending($imgPng, true);
        imageSaveAlpha($imgPng, true);
        header("Content-type: image/png");
        imagePng($imgPng); 
        $i = ob_get_contents();
        $attachment = chunk_split(base64_encode($i));
        // clear the buffer, but don't destroy it
        ob_clean();
        // Define Body
        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 is the information for laptop problems.  Your signature is attached to this e-mail.

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

        <h2>Hello World!</h2>
        <p>This is something with <b>HTML</b> formatting.</p>
        <img src="cid:signature.png" />
        --PHP-alt-<?php echo $random_hash; ?>--

        --PHP-mixed-<?php echo $random_hash; ?> 
        Content-Type: application/zip; name="signature.png" 
        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();

        $mail = new \helpdesk\core\mail("email@example.com", $subject, $message);
        $mail->setHeaders($headers);
        $mail->send();
        unset($mail);
    }

Can someone tell me what I am doing wrong here?

Bil1
  • 440
  • 2
  • 18
  • Why do you have `$headers[]` in brackets? I've never seen that before, or is there something I wasn't aware of? I've usually seen (if there's more than one) `$headers=` `$headers.=` (second and so on, takes a DOT). Just saying. – Funk Forty Niner Apr 15 '13 at 13:47
  • Sorry. The setHeaders function of the mail object actually does an implode "\r\n" on the headers array. This is just to make it cleaner. I read it somewhere and like it. – Bil1 Apr 15 '13 at 13:48
  • I may also note that the mail object works fine. All it does is set the to, subject, and message when created. setHeaders formats a header array and sets the headers. Then send simply calls mail with these properties. – Bil1 Apr 15 '13 at 13:50
  • One thing that seems strange to me is, `Content-Type: application/zip; name="signature.png"` A ZIP set for a PNG. – Funk Forty Niner Apr 15 '13 at 13:53
  • I commented all of the extra code before what was in test.php and it still failed. Sends me an e-mail like this: --PHP-mixed-a1dcf522ab918b8fd0a2b247670101e0 Content-Type: multipart/alternative; boundary="PHP-alt-a1dcf522ab918b8fd0a2b247670101e0" --PHP-alt-... It has to be the fact that it is in an object or something... – Bil1 Apr 15 '13 at 13:54
  • Only thing I can tell is the `application/zip;` - the encoding attachment shouldn't be `Zip` for an `image`, far as I know. Unless you're zipping the image(?) – Funk Forty Niner Apr 15 '13 at 13:58
  • I thought that was strange too however it works in the test.php file that way. I had changed it to image/png but until I get it working in the real environment I didn't want to keep a change to the original code. that will be changed after I get it working. – Bil1 Apr 15 '13 at 13:59
  • Could it be the header call header("Content-type: image/png");? This is within a php file that is doing alot so I don't know if it is breaking things... – Bil1 Apr 15 '13 at 14:02
  • Try commenting it out (`header("Content-type: image/png");`) and see – Funk Forty Niner Apr 15 '13 at 14:03
  • Commented the header line in both test.php and within the main program and it behaves no different. – Bil1 Apr 15 '13 at 14:06
  • Is the PNG image dynamically created, or it this a standard image file on your server? – Funk Forty Niner Apr 15 '13 at 14:11
  • the image is dynamic. I have tested it using a copy and paste of some data that I know is valid and that is how I am testing it now. The data is a signature. I just did a print_r of $message and $headers and they are identical for both test.php and progress.php (the main file) – Bil1 Apr 15 '13 at 14:18
  • Try adding a `"MIME-Version: 1.0\r\n";` somewhere, on top of other headers. I.e. `charset=ISO-8859-1`. I don't know what it else it could be, sorry. – Funk Forty Niner Apr 15 '13 at 14:22
  • 1
    I JUST FIGURED IT OUT! when I copied and pasted the code over I tabbed it up since it was within a function. Well the tab added a tab to the image data which is why it was wrong. YOu can't tabe direct output... I want to give you credit for helping me. Post an answer and i'll give you credit. – Bil1 Apr 15 '13 at 14:31
  • Heyyy that's great, happy to hear it! – Funk Forty Niner Apr 15 '13 at 14:32

1 Answers1

1

Check for any added characters, spaces or tabs in your image data.

Funk Forty Niner
  • 74,450
  • 15
  • 68
  • 141
  • Thanks to Fred's help this is fixed! If you look at the code examples, the second one is indented. Which means that when you get to Content-Disposition: attachment There is a tab before the image data which caused the errored code. – Bil1 Apr 15 '13 at 14:36
  • 1
    @Bil1 You're welcome. It's always better to have more people on this, and doing it early in the morning. Some don't sleep in trying to figure stuff out like that. A `clear mind` leads to `solutions`. All the best, cheers! – Funk Forty Niner Apr 15 '13 at 14:41