Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

First time poster, be gentle. Anyway I'll try and make this as clear as possible.

I have a site that uses a combination of jQuery/Ajax and PHP to create offer 'coupons'. When a user visits, they select the coupons they want to buy (via PayPal) and submit. I'm sending this to paypal and listening for the IPN within my PHP script and in the case of a Valid IPN the script should proceed to assign a randomly generated 12 digit 'barcode' to the coupons they chose, add them all to a file that is opened for printing. I'm storing the selected coupon data (name array) using this jQuery plugin

The initial coupon generation works, the paypal integration (including the IPN listener) works. I can see the cookies in the console while I'm testing this so my form data is there. I'm even getting the 'success' portion of the json array.

My issues is that I'm trying to fetch the image file via ajax but I am getting 'SyntaxError: JSON.parse: unexpected end of data' and I can't figure out why. The image creation code was already written prior to me taking this on, I just needed to tie it together with paypal.



my-offers.php

$(window).load(function(){

  var extradata = {};
  extradata.action = 'createCoupon';
  extradata.offers = $.cookies.get("offers");
  console.log(extradata);
    $.ajax({
      url: 'api/data_request.php',
      success: function(e, data, result){
          console.log('done!', data);   
              //this returns 'success' but console.log('done!', e) returns empty string

        //below is throwing unexpected end of data
        var resultObj = JSON.parse(e);
                        if(resultObj.result === 'success'){
                            //console.log('success!'+resultObj);
                            window.open(resultsObj.filename, '_blank');
                        }else{
                            console.log('some sort of error!', data);
                        }
                    },
                    type: 'POST',
                    data: extradata,
                    error: function(e, data, extra){
                            console.log('there was a serious error!', e, data, extra);
                            console.log(data.errorThrown, data.textStatus, data.jqXHR);
                    }                       
                });



data-request.php

//go through finished coupons array, and put them all on one image
            //then save the image in coupons
            $finalimg = imagecreatetruecolor($thewidth, $theheight);
            $cursor = 0;
            for($i = 0; $i<4; $i++){
                $obj = $finishedCoupons[$i];
                $coupon = $obj[0];
                $width = $obj[1];
                $height = $obj[2];
                $copyied = imagecopymerge($finalimg, $coupon, 0, $cursor, 0, 0, $width, $height, 100); 
                if($copyied === false){
                    returnError('error copying images');
                }
                $cursor = $cursor+$height;
            }
            $didit = imagejpeg($finalimg, '/images/coupons/'.$thefilename.'.jpg', 100);
            if($didit === false){
                returnError('final copying error'.$thefilename);
            }else{


                echo json_encode(array('result'=>'success', 'filename'=>'images/coupons/'.$thefilename.'.jpg'));
                die();

            }



MySQL select the coupons and create barcodes (for context)

//get the coupon picture we'll put the numbers on
                    $success1 = $mysqli->prepare("SELECT title, text, realcoupon FROM offers WHERE offer_id = ? LIMIT 1");
                    $success1->bind_param('i', $coupon);
                    $success1->execute();
                    $success1->store_result();
                    $success1->bind_result($title, $text, $source);
                    $success1->fetch();                 
                //now actually generate the numbers
                //perform database collision detection
                //number is 12 digits long so we can use it in a barcode if needed
                    $exists = 1;
                       while($exists !== 0){ 
                        $code = generateRandomNumber();
                        $success1 = $mysqli->prepare("SELECT barcode FROM offerId WHERE barcode = ?");
                        $success1->bind_param('s', $code);
                        $success1->execute();
                        $success1->store_result();
                        $exists = $success1->num_rows;
                       }
                    $thefilename.=$code;
                //$code is a unique barcode now, so we should insert it into the array
                // coupon contains the offer_id
                $success = $mysqli->prepare("INSERT INTO offerId (offer_id, barcode, date) VALUES (?, ?, CURRENT_TIMESTAMP)");
                $success->bind_param('is', $coupon, $code);
                $success->execute();
                //$success->store_result();
                //$success->fetch();
                $affected = $success->affected_rows;
                if($affected !== 1){
                    returnError($affected);
                    returnError('Error inserting the barcode!');
                }                   
                //now put the numbers on the coupon and push it to the finishedCoupons array
                $source = '../images/'.$source;
                try{
                   $extension = pathinfo($source, PATHINFO_EXTENSION);
                   if(!file_exists($source)){
                    returnError('Cant find coupon!');
                    return false;
                   }
                   $info = getimagesize($source);
                   if($info === false){
                      returnError("InvalidImage");
                      return false;
                   }
                }catch (Exception $e){
                    returnError("InvalidImage");
                    return false;
                }
                $type    = $info[2];
                $width   = $info[0]; // you don't need to use the imagesx and imagesy functions
                $height  = $info[1];
                if($width>$thewidth){
                    $thewidth = $width;
                }

I've tried setting the php file to header('Content-type: application/json'); I've tried calling dataType: 'json' in my ajax call. I've even run php -l data_request.php to check for syntax errors and nothing was returend. Nothing seems to work. This is the last step I need to debug!! I've been working on this for hours.

UPDATE: After inspecting the response header, it looks like it's being transferred as type text/html instead of text/json or application/json

share|improve this question
    
I would not expect an image to be returned as JSON. Also, knowing which line is throwing that error would be most useful. –  cale_b Mar 1 '14 at 3:30
    
So from what I can tell the original programmer added the image file paths to MySQL which is what we are pulling with the data_request.php and passing to JSON which we then get via ajax. As for the error it's this: var resultObj = JSON.parse(e); which is getting the error. Obviously there's nothing wrong there, there's something missing in the JSON I think which is what is causing this error I just can't spot it. –  dylanf Mar 1 '14 at 5:07
    
For better context you can see it live at renotahoepromos.com/custom-offer and renotahoepromoscom/my-offers –  dylanf Mar 1 '14 at 5:15

2 Answers 2

The last line of your PHP is the problem:

echo json_encode(array('result'=>'success', 
                       'filename'=>'images/coupons/'.$thefilename.'.jpg'));
die(); echo $coupons;

When you write PHP services, you should only be echo'ing the JSON nothing else, or the JSON response data won't be valid since it is being concatenated with another string.

You must echo JSON ONLY:

echo json_encode(array('result'=>'success', 
                       'filename'=>'images/coupons/'.$thefilename.'.jpg'));
die(); //echo $coupons;
share|improve this answer
    
Yea I added that in there earlier to test I was receiving the cookie data correctly. I am, and I took that out and still the same issue. It's either not fetching the coupon image paths or is failing somewhere in creating the new image with the barcode. I'm still getting the unexpected end of input. What I see in the console is my cookie data, plus the console.log('data!', data); which gives me data! success (the first part of the JSON) –  dylanf Mar 2 '14 at 0:51

Found the issue.

IPN is not real time, and since the client here needed to interrupt the payment flow here in the case that the payment (ipn) failed, this didn't work, which in turn caused the JSON to be partially empty since it was wrapped in an if() with the paypal IPN. So I changed this out with paypal PDT (payment data transfer) which is instant, and then verified against the transaction id and payment amount.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.