I am doing a fairly large implementation using the exposed APIs of all 4 major shippers. I’ve posted a few notes on USPS, and I’ve been using UPS for so long it almost seems to make perfect sense.
So, while I have to applaud FedEx for the granularity and versatility of the API they have exposed, it has caused me severe headaches due to the PHP SimpleXML issues it brings up with SOAP envelopes — particularly nested soap envelopes.
Long story short, the jist of this post is to help others deal with the responses they receive from the FedEx servers (if, like me, their pre-packaged methods do not implement tidily into your application structure).
Here is a sample response of a rate request (NOTE: this is a “Warning” response, only here for demo purposes):
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<env:Header xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
<env:Body xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<v8:RateReply xmlns:v8="http://fedex.com/ws/rate/v8">
<v8:HighestSeverity>WARNING</v8:HighestSeverity>
<v8:Notifications>
<v8:Severity>WARNING</v8:Severity>
<v8:Source>crs</v8:Source>
<v8:Code>556</v8:Code>
<v8:Message>There are no valid services available. </v8:Message>
<v8:LocalizedMessage>There are no valid services available. </v8:LocalizedMessage>
</v8:Notifications>
<v8:TransactionDetail xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
<v8:CustomerTransactionId>TC05_Rate_Package_Groups_POS</v8:CustomerTransactionId>
</v8:TransactionDetail>
<v8:Version xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
<v8:ServiceId>crs</v8:ServiceId>
<v8:Major>8</v8:Major>
<v8:Intermediate>0</v8:Intermediate>
<v8:Minor>0</v8:Minor>
</v8:Version>
</v8:RateReply>
</env:Body>
</soapenv:Envelope>
There are lots of ways you might envision accessing that precious “RateReply” tag, but to keep it simple and avoid inferences, you get to it like this:
$xml = simplexml_load_string ($xml_from_above);
$xml->children(‘http://schemas.xmlsoap.org/soap/envelope/’)->Body->children(‘http://fedex.com/ws/rate/v8′)->RateReply;
I do suppose this is obvious enough, but believe me, the nuances that can throw it off can still cause you to inadvertently lose ridiculous amounts of time on it.
Furthermore, if you prefer to do direct PHP cURL XML calls (which you probably do given that you’re reading this), you’ll find that FedEx is not terribly interested in your type of programmer. To find a simple sample XML call, you’ll have a tough time (although I managed to find it in the WSDL downloadable ZIP). However, this is a very basic call. To add additional data (such as the exotic field that apparently no one would ever think to use — “InsuredValue”) — this field has the form (EXACTLY, stuff in brackets is what can be changed) “<InsuredValue><Currency>[currencytype]</Currency><Amount>[float]</Amount></InsuredValue>”
The “InsuredValue” node/field must go immediately before the “Weight” node in the “RequestedPackageLineItems” node. (This of course reference FedEx API v8 — things may be different in future releases.)
WordPress 3.0, multi-sites, and migrating only some of your posts
I started my original blog a little over a year ago now simply as a way to have a place to post thoughts online. As it progressed and I started to flesh out my music site, I realized that I actually have at least 3 distinct types of thoughts I want to post: music-related, general commentary on my life, hobbies, and interests, and philosophical topics.
WordPress is extremely powerful, and I quickly began using its RSS functionality to feed my music related posts to my music website, but, as it turns out, this is kind of bad from a search engine perspective. I ended up using cross-domain canonical URLs to make Google happy. Additionally, it was kind of confusing. While I don’t really have much traffic to any of my sites, I like to pretend that I do, and it just wasn’t adding up.
Then comes WordPress 3.0 which allows you to host multiple blogs (even, unofficially, on multiple domains), so it gave me the opportunity to allocate content correctly to my domains.
There are drawbacks, of course. It’s not like you get to just make posts and decide which domain you want it on. You still have separate sites with separate management profiles, etc., it’s just that anytime you upgrade core components (such as themes, plugins, and even WordPress itself) you don’t have to do it for every blog.
Plus, all your content is in a centralized, easily accessible place. Perhaps in the future more fine-tuned enhancements will evolve, but for the time being all I had to do was some MySQL footwork (in moving the right posts to the right blogs, which was simple enough as I already had “Music” and “Philosphy” categories).
I have had crimulus.com reserved for some time as my “personal” site — projects I’m working on, hobby showcases, etc., but I never really fleshed it out. My music site, jeremytharp.com, is about 5 years old now, but it relayed podcast data, music news, etc. for anyone visiting that site, but, for a search engine, it treated it as if it were hosted on my actual blog which is at coffeecuphalfmoons.com.
To summarize, I just wanted to express how pleased I am with the feature as well as inform any readers (if you exist) of the changes.
Finally, for the technological grit, if anyone else intends to do this, I had to make a modification to my coffeecuphalfmoons.com theme.
I had plenty of indexed content, so now most of those are on crimulus.com or blog.jeremytharp.com, so links from search engines would generate a 404. I simply modified my theme’s index.php send a GET request for the $_SERVER['REQUEST_URI'] on each of the domains (crimulus.com and blog.jeremytharp.com) in the event that have_posts() returned false. If either of those requests returns a header code other than 404, I send a 301 redirect for that.
So, a search engine refers a user to http://www.coffeecuphalfmoons.com/a/post/that/i/moved/
I check (using cURL) to see if http://www.crimulus.com/a/post/that/i/moved/ or http://blog.jeremytharp.com/a/post/that/i/moved/ returns a 200, 301, etc. If so, then it’s probably the post that was originally referred to.
This is how you help keep pagerank value and link-juice when you’re migrating only a few posts from a blog on one domain to a blog on another. At least, that’s how I did it.
Posted in Commentary, Computers, Reviews