Posts Tagged ‘XML’

5 Reasons to get a new CMS

February 24th, 2010 by Bobby Whitman

Over the past few years we’ve worked with dozens of different content management systems with varying levels of usability and workability. In a current engagement with a client we find ourselves having to learn yet another. Although this new system is actually very usable from a content editor’s point of view, it suffers from many of the following pitfalls.

5. Invalid XHTML

Writing valid XHTML enhances accessibility and sets your site up for forward compatibility. It is also the only way to ensure that your site will render correctly in all of today’s browsers and non-traditional devices. All code your developers write should be valid XHTML, expect nothing less from your CMS.

4. Missing or incorrect DOCTYPE

The DOCTYPE part of a document informs the browser what type of code is following and, as a result, how to render the page on the screen. It is not uncommon that a CMS automatically places a seemingly innocent copyright notice on the top of every page. What they may not realize is that unless the DOCTYPE is the very first thing on the page it does not take effect. This means that you could write perfectly valid XHTML code but because the DOCTYPE has been killed by your CMS, your site will not appear correctly in all browsers.

3. No RSS/XML support

XML/RSS is a great way to provide content. It allows users and other applications to pull in the data and use your content elsewhere, all the while linking back to your site. Today’s web is made up of streams in the form of news, events, status updates, etc. Your CMS should be able to participate in this form of sharing information.

2. No Support

A CMS is designed to only cover about 60 to 70% of updates necessary for maintaining a quality website, and even then no CMS is perfect. You will need help, whether it is design or development support for the site as a whole or dealing with the imperfections of your CMS.

1. Messy URLs

Your choice www.dynamit.us/index.php?action=content.display&id=7478&category=1212 or www.dynamit.us/services/web-development. There are tons of good reasons to want clean URLs: more user-friendly when linking, keyword-rich and good for SEO, indicative of a user’s place within a site architecture. The technology is there to make it happen, but your CMS has to be able to handle it.

Want to see what we’re talking about for yourself? Shoot us a note at info@dynamit.us to schedule a walk-through of our dCMS 5.0.

Integrating UPS Online Tools with PHP/mySQL e-commerce

February 12th, 2008 by Bobby Whitman

Today, I was faced with a brand new challenge. A client had contracted us to create an online store complete with custom shopping cart and payment gateway interaction. After carefully considering business logistics, the client decided to do all of the shipping of online sales using UPS. So, in order to accurately calculate shipping costs to pass along to the customer we were asked to integrate UPS Online Tools into the checkout process we were designing. The goal was to have the client select their preferred method of shipping, display the cost for UPS to ship to their zip code, and have that cost added to the total so it could be charged to the customer’s credit card.

“No problem,” I thought. Surely, UPS has a great API with tons of resources and sample scripts, right? Well, not so much. All I really got out of them was a 63 page PDF filled mostly with XML 101 and an error code reference. The only sample code I could find was written Java and Visual Basic. After all, who needs samples in popular web languages like ASP, ColdFusion, Perl, and PHP?

Ok, so let’s turn to Google, surely someone has done this before and is willing to share their source with the community, right? Again, no luck. I googled for the better part of an hour finding nothing more than some software piece for sale claiming to do it and a bunch of unanswered forum posts from about 4 years ago.

Looks like I am on my own. So, I rolled up my sleeves and started poking around the UPS service and I have what I think is a good solution. Now, I am writing this resource paper so I can share this solution with all, so the next person looking need go no farther.

Goal: Given a destination city/zip/country, an approximate weight of the package, and the type of shipping service I want to order from UPS (e.g. 2nd day air, ground, etc.) be able to calculate shipping rates on the fly and store that data in my database so I can record it as part of the order.

To achieve this end I will want to use the UPS Rates and Service Selection XML Tool. In order to use this, I will need an account at UPS.com and what is called a Developer’s Key that you can use to generate an XML Access Key.

This tool works as follows:
1. You format a request using XML and the format specified by UPS. This format is explained in the Developer’s Guide provided by UPS.
2. Send this request to the UPS service via HTTP POST.
3. The UPS service will then output a response in XML.

When we get this response from UPS we can parse the resultant XML using PHP and retrieve the data we desire.

Step 1: Create the XML using the correct format for UPS.

Essentially there is two things we must do here. First, we have to gain access to the UPS service. We do this by sending an AccessRequest through XML. In this exmaple, your ‘UserId’ and ‘Password’ make up your UPS.com login and ‘AccessKey’ is the XML Access Key generated through UPS.com.

<?xml version=”1.0″?>
<AccessRequest xml:lang=”en-US”>
<AccessLicenseNumber>AccessKey</AccessLicenseNumber>
<UserId>UserId</UserId>
<Password>Password</Password>
</AccessRequest>

Second, we send data regarding the shipment for which we want costs calculated. We take these two XML files, concatenate them, and send them both in our request.

<?xml version=”1.0″?>
<RatingServiceSelectionRequest xml:lang=”en-US”>
<Request>
<RequestAction>Rate</RequestAction>

<RequestOption>Rate</RequestOption>
</Request>
<Shipment>
<Shipper>
<ShipperNumber>ShipperNumber</ShipperNumber>
<Address>
<City>Columbus</City>

<PostalCode>43220</PostalCode>
<CountryCode>US</CountryCode>
</Address>
</Shipper>
<ShipTo>
<Address>
<City>Cincinnati</City>

<PostalCode>45207</PostalCode>
<CountryCode>US</CountryCode>
</Address>
</ShipTo>
<ShipFrom>
<Address>
<City>Columbus</City>

<PostalCode>43220</PostalCode>
<CountryCode>US</CountryCode>
</Address>
</ShipFrom>
<Service>
<Code>03</Code>
</Service>

<Package>
<PackagingType>
<Code>02</Code>
<Description>Customer Supplied</Description>
</PackagingType>
<Description>Rate</Description>
<PackageWeight>

<UnitOfMeasurement>
<Code>LBS</Code>
</UnitOfMeasurement>
<Weight>10</Weight>
</PackageWeight>
</Package>
</Shipment>
</RatingServiceSelectionRequest>

You can pretty much see what is going on here. But to clarify, we send details about the Request and the Shipment, which involves the following information:

Shipper – UPS assigned ShipperNumber and general info about the shipper.
ShipTo – Critical information (city, zip code, and country) on the shipment destination.
ShipFrom – Critical information (city, zip code, and country) on the shipment source.
Package – Information about the package including packaging type and weight of package.
Service – A code for the UPS service to use. See Below.

<?

$ups_service = array(
’01′ => ‘UPS Next Day Air®’,
’02′ => ‘UPS Second Day Air®’,
’03′ => ‘UPS Ground’,
’12′ => ‘UPS Three-Day Select®’,
’13′ => ‘UPS Next Day Air Saver®’,
’14′ => ‘UPS Next Day Air® Early A.M. SM’,
’59′ => ‘UPS Second Day Air A.M.®’,
’65′ => ‘UPS Saver’,
);

?>

Note that you may choose receive information on the costs of all UPS products for this shipment. In this case we change the RequestOption to ‘Shop’ and omit the ‘Service’ node.

This is the basic structure of the XML, there are a number of additional fields you may specify regarding the Shipment, for more information here, please refer to the Developer’s Guide provided by UPS.

Next, I am going to use some PHP so we can parameterize the critical information:

<?

$destCity = $_POST['x_ship_to_city'];
$destZip = $_POST['x_ship_to_zip'];
$destCountry = ‘US’;

$shipWeight = $_POST['ship_weight'];
$shipType = $_POST['ship_method'];

$shipperNumber = ‘ENTER SHIP NUMBER’;

$myCity = ‘Columbus’;
$myZip = ’43220′;
$myCountry = ‘US’;

$accessLicense = ‘ENTER ACCESS KEY’;
$userId = ‘ENTER USER ID’;
$password = ‘ENTER PASSWORD’;

$XML = ‘<?xml version=”1.0″?>
<AccessRequest xml:lang=”en-US”>
<AccessLicenseNumber>’ . $accessLicense . ‘</AccessLicenseNumber>
<UserId>’ . $userId . ‘</UserId>
<Password>’ . $password . ‘</Password>
</AccessRequest>
<?xml version=”1.0″?>
<RatingServiceSelectionRequest xml:lang=”en-US”>
<Request>
<RequestAction>Rate</RequestAction>
<RequestOption>Rate</RequestOption>
</Request>
<Shipment>
<Shipper>
<ShipperNumber>’ . $shipperNumber . ‘</ShipperNumber>
<Address>
<City>’ . $myCity . ‘</City>
<PostalCode>’ . $myZip . ‘</PostalCode>
<CountryCode>’ . $myCountry . ‘</CountryCode>
</Address>
</Shipper>
<ShipTo>
<Address>
<City>’ . $destCity . ‘</City>
<PostalCode>’ . $destZip . ‘</PostalCode>
<CountryCode>’ . $destCountry . ‘</CountryCode>
</Address>
</ShipTo>
<ShipFrom>
<Address>
<City>’ . $myCity . ‘</City>
<PostalCode>’ . $myZip . ‘</PostalCode>
<CountryCode>’ . $myCountry . ‘</CountryCode>
</Address>
</ShipFrom>
<Service>
<Code>’ . $shipType . ‘</Code>
</Service>
<Package>
<PackagingType>
<Code>02</Code>
<Description>Customer Supplied</Description>
</PackagingType>
<Description>Rate</Description>
<PackageWeight>
<UnitOfMeasurement>
<Code>LBS</Code>
</UnitOfMeasurement>
<Weight>’ . $shipWeight . ‘</Weight>
</PackageWeight>
</Package>
</Shipment>
</RatingServiceSelectionRequest>’;

?>

Step 2: Post the XML to UPS.

Now that we have generated a properly formatted request we need to send this to the UPS service for real-time processing. To do so, we will uses PHP built-in CURL functions. If you are not familiar with CURL, get more here: http://curl.haxx.se/, or here: http://us2.php.net/manual/en/ref.curl.php. The following code connects to the UPS server, POSTS the XML data, and returns the HTTP output to the $resp variable. As a result, $resp is now a string containing the XML that UPS has sent back. If you request was successful, this XML contains the shipping cost data that we want.

<?

$ch = curl_init(“https://wwwcie.ups.com/ups.app/xml/Rate”);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $XML);

$resp = curl_exec($ch);

curl_close ($ch);

?>

Step 3: Parsing the response XML with PHP.

Finally, we have the correct response from the UPS server. We need to parse this XML data to get what we want into our database or at the very least a PHP variable so we can add it to the total of the shipment. For this I will use the SimpleXML class that is built into PHP 5+.

<?

$data = new SimpleXMLElement($resp);

?>

This will load all the XML data conveniently into a PHP object. Drop in a and you will see exactly what we have to work with. We can then hack through the XML structure fairly easily to get what we want, or use XPath to essentially query our XML.

<?

$cost = (double)$data->RatedShipment->TotalCharges->MonetaryValue;

?>

The variable $cost now has the shipping price that we need to charge our online customer. You can now use this data in your existing e-commerce application.

Lastly, suppose you wish to display all UPS shipping services with their associated prices so that your customer could make a choice based on price. As I mentioned above you can change the RequestOption node in your request XML to have a value of ‘Shop’. If this modification is made, the UPS XML response includes multiple RatedShipment nodes, one for each service. If this is the case, we can use the snippet below to build an array where our keys are the UPS shipping service codes and the values are the associated costs.

<?

$shipping = array();
foreach($data->RatedShipment as $rate) {

$service = (string)$rate->Service->Code;
$cost = (double)$rate->TotalCharges->MonetaryValue;

$shipping[$service] = $cost;

}

?>