0

I'm trying to integrate UPS shipping label printing functionality into a custom crm/shopping cart app. I'm forming the xml document using a php stdClass object. I pass the method an array containing the package(s) variables ex.

    $pkgs = Array ( [1] => Array ( [length] => 6 [width] => 8 [height] => 11 [weight] => 5 ) [2] => Array ( [length] => 5 [width] => 14 [height] => 10 [weight] => 9 ) )

My xml building method looks like this

public function assemble_xml($pkgs){
    $xmlRequest = new stdClass();
    $xmlRequest->header="<?xml version='1.0'?>
<AccessRequest xml:lang='en-US'>
<AccessLicenseNumber>HIDDEN</AccessLicenseNumber>
<UserId>HIDDEN</UserId>
<Password>HIDDEN</Password>
</AccessRequest>
<?xml version='1.0'?>
<ShipmentConfirmRequest xml:lang='en-US'>
<Request>
    <TransactionReference>
        <CustomerContext>Customer Comment</CustomerContext>
        <XpciVersion/>
    </TransactionReference>
    <RequestAction>ShipConfirm</RequestAction>
    <RequestOption>validate</RequestOption>
</Request>
<LabelSpecification>
    <LabelPrintMethod>
        <Code>GIF</Code>
        <Description>gif file</Description>
    </LabelPrintMethod>
    <HTTPUserAgent>Mozilla/4.5</HTTPUserAgent>
    <LabelImageFormat>
        <Code>GIF</Code>
        <Description>gif</Description>
    </LabelImageFormat>
</LabelSpecification>
<Shipment>
    <RateInformation>
        <NegotiatedRatesIndicator/>
    </RateInformation>
    <Description/>
    <Shipper>
        <Name>HIDDEN</Name>
        <PhoneNumber>HIDDEN</PhoneNumber>
        <ShipperNumber>HIDDEN</ShipperNumber>
        <TaxIdentificationNumber>HIDDEN</TaxIdentificationNumber>
        <Address>
            <AddressLine1>HIDDEN</AddressLine1>
            <City>HIDDEN</City>
            <StateProvinceCode>HIDDEN</StateProvinceCode>
            <PostalCode>HIDDEN</PostalCode>
            <PostcodeExtendedLow></PostcodeExtendedLow>
            <CountryCode>HIDDEN</CountryCode>
        </Address>
    </Shipper>";
    $xmlRequest->shipto="<ShipTo>
        <CompanyName>HIDDEN</CompanyName>
        <AttentionName>HIDDEN</AttentionName>
        <PhoneNumber></PhoneNumber>
        <Address>
            <AddressLine1>HIDDEN</AddressLine1>
            <City>HIDDEN</City>
            <StateProvinceCode>HIDDEN</StateProvinceCode>
            <PostalCode>HIDDEN</PostalCode>
            <CountryCode>HIDDEN</CountryCode>
        </Address>
    </ShipTo>";
    $xmlRequest->shipper="<ShipFrom>
        <CompanyName>HIDDEN</CompanyName>
        <AttentionName></AttentionName>
        <PhoneNumber>HIDDEN</PhoneNumber>
        <TaxIdentificationNumber>HIDDEN</TaxIdentificationNumber>
        <Address>
            <AddressLine1>HIDDEN</AddressLine1>
            <City>HIDDEN</City>
            <StateProvinceCode>HIDDEN</StateProvinceCode>
            <PostalCode>HIDDEN</PostalCode>
            <CountryCode>HIDDEN</CountryCode>
        </Address>
    </ShipFrom>";
    $xmlRequest->payment="<PaymentInformation>
        <Prepaid>
            <BillShipper>
                <AccountNumber>HIDDEN</AccountNumber>
            </BillShipper>
        </Prepaid>
    </PaymentInformation>";
    $xmlRequest->service="<Service>
        <Code>03</Code>
        <Description>Ground</Description>
    </Service>";
    for($i = 1; $i <= count($pkgs); $i++)  {
        $xmlRequest->$i ="<Package>
        <PackagingType>
            <Code>02</Code>
            <Description>Customer Supplied</Description>
        </PackagingType>
        <Description>Package</Description>
        <ReferenceNumber>
            <Code></Code>
            <Value></Value>
        </ReferenceNumber>
        <Dimensions>
            <UnitOfMeasurement>
                <Code>IN</Code>
            </UnitOfMeasurement>
                <Length>22</Length>
                <Width>20</Width>
                <Height>18</Height>
        </Dimensions>
       <PackageWeight>
        <Weight>14.1</Weight>
        </PackageWeight>
        <AdditionalHandling>0</AdditionalHandling>
    </Package>";
    }
    $xmlRequest->footer="</Shipment>
</ShipmentConfirmRequest>";
return $xmlRequest;

Cool that works. Now I feed it thru a few other functions to get my digest.

    public function ups_send($assemble_xml){
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, "https://wwwcie.ups.com/ups.app/xml/ShipConfirm");
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $assemble_xml);
    curl_setopt($ch, CURLOPT_TIMEOUT, 3600);
    $xmlResponse = curl_exec ($ch);
    return $xmlResponse;



    public function get_confirm_response($xmlResponse){
    preg_match_all( "/\<ShipmentConfirmResponse\>(.*?)\<\/ShipmentConfirmResponse\>/s",
    $xmlResponse, $bookblocks );
    foreach( $bookblocks[1] as $block )
    {
    preg_match_all( "/\<ShipmentDigest\>(.*?)\<\/ShipmentDigest\>/",
        $block, $author ); // SHIPPING DIGEST

    $digest = $author[1][0];
    $this->decode_label($digest);

    }
    }



    public function decode_label($digest){
    $xmlRequest1="<?xml version='1.0' encoding='ISO-8859-1'?>
                    <AccessRequest>
                            <AccessLicenseNumber>HIDDEN</AccessLicenseNumber>
                        <UserId>HIDDEN</UserId>
                        <Password>HIDDEN</Password>
                    </AccessRequest>
                    <?xml version=”1.0? encoding=”ISO-8859-1??>
                    <ShipmentAcceptRequest>
                        <Request>
                            <TransactionReference>
                                <CustomerContext>Customer Comment</CustomerContext>
                            </TransactionReference>
                            <RequestAction>ShipAccept</RequestAction>
                            <RequestOption>1</RequestOption>
                        </Request>
                        <ShipmentDigest>$digest</ShipmentDigest>
                    </ShipmentAcceptRequest>";

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, "https://wwwcie.ups.com/ups.app/xml/ShipAccept");
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $xmlRequest1);
    curl_setopt($ch, CURLOPT_TIMEOUT, 3600);

    $xmlResponse = curl_exec ($ch); // SHIP ACCEPT RESPONSE

    $xml = $xmlResponse;



    preg_match_all( "/\<ShipmentAcceptResponse\>(.*?)\<\/ShipmentAcceptResponse\>/s",
        $xml, $bookblocks );

    foreach( $bookblocks[1] as $block )
    {

        preg_match_all( "/\<GraphicImage\>(.*?)\<\/GraphicImage\>/",
        $block, $author ); // GET LABEL


        for($l=0; $l<=count($author[0])-1; $l++){

            echo '<img src="data:image/gif;base64,'. $author[1][$l]. '"/>';

        }

    }

}

This all works with 1 or 2 labels, the labels are successfully decoded into label 1 of 2 and 2 of 2. BUT when I try to make 3 or more labels I get a successful response xml from UPS but I no labels are generated. I have been banging my head against my desk for days over this and could really use the expertise of SO to give me a nudge in the right direction about what I'm doing wrong. Why does 1 or 2 labels work but 3 or more doesn't? WHAT GIVES!

If its the regex thats wrong then why does it work if only 2 labels are requested?

There is a postscript you might be interested in.

Here is a pastebin of the xml response from UPS containing the labels.

http://pastebin.com/h3nhNQ0R

6
  • have you tried posting this in the UPS developer community as this maybe a little specific for here? Commented Jan 16, 2014 at 18:05
  • No I haven't, I will do it tho. The main reason I didn't is because I'm getting a successful response from UPS. I just can't seem to parse it correctly if I request more than 3 labels. If I only request 1 or 2 labels it works like a charm. I figured it was some kind of programming logic problem. Thanks for taking the time to respond, I truly appreciate it! Commented Jan 16, 2014 at 18:10
  • 1
    Obligatory link for all XML/[X]HTML-regex questions. Commented Jan 16, 2014 at 18:14
  • no problem, i'm not sure many people will have much experience with the API and the developer community will have much more experience in with these issues Commented Jan 16, 2014 at 18:14
  • 1
    See this question and answer why you shouln't use regex for parsing XML. There are a lot of great libraries for PHP to parse XML Commented Jan 16, 2014 at 20:38

1 Answer 1

1

After reading the links you folks provided, I learned that not only was I losing my mind trying to do this when clearly a more appropriate solution was available but also

"Giving in to Them and their blasphemous ways which doom us all to inhuman toil for the One whose Name cannot be expressed." ~bobince

I replaced this unholy weeping child

    preg_match_all( "/\<ShipmentAcceptResponse\>(.*?)\<\/ShipmentAcceptResponse\>/s",
        $xml, $bookblocks );

    foreach( $bookblocks[1] as $block )
    {

        preg_match_all( "/\<GraphicImage\>(.*?)\<\/GraphicImage\>/",
        $block, $author ); // GET LABEL


        for($l=0; $l<=count($author[0])-1; $l++){

            echo '<img src="data:image/gif;base64,'. $author[1][$l]. '"/>';

        }

    }

with this beautiful solution

    $label_resp = new SimpleXMLElement($xml);
    foreach($label_resp->ShipmentResults->PackageResults as $package ){
        echo '<img src="data:image/gif;base64,'. $package->LabelImage->GraphicImage. '"/>';
    }

Not only does it worked perfectly, it also runs circles around the original solution speed wise.

Thank you, saviors of mankind, for your push in the right direction.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.