Create and list new tickets through the Assembla API

A while back I created a PHP library for interacting with the Assembla Ticket API. I thought it might be useful to someone, so here it is.

You can use this library to create and list tickets that exist for one of your Assembla spaces. It’s useful for integrating bug reporting and other feedback features into an application that you may be developing. This code is very much a work in progress, so please let me know if you encounter any bugs or have any new feature requests.

You can view and download the code on GitHub:

github-logo

Virtuemart – shipping method list – invalid markup

virtuemart-shipping-method-list

A user recently reported an odd problem on a Virtuemart site I maintain. They weren’t able to properly select the bottom two shipping methods listed (both USPS options).

I took a gander at the cart and quickly found the problem. The UPS shipping module was outputting the radio buttons wrapped in a <label> tag. Problem was, it wasn’t doing this consistently, and the last UPS shipping option had an open tag that was encompassing all the remaining radio buttons. This meant that anywhere you clicked in that region would result in the last UPS option being selected.

Now for some reason the USPS shipping module didn’t output labels at all. So I figured the most consistent solution would be to simply prevent the UPS module from outputting those <label> tags.

The method you’re looking for is ups::list_rates(), which is in the ./administrator/components/com_virtuemart/classes/shipping/ups.php file.

You can see the changes I made below on lines 362 and 384. The lines that are commented out are the original ones.

  1. $shipping_rate_id = urlencode(__CLASS__."|UPS|".$value['ServiceName']."|".$charge);
  2. $checked = (@$d["shipping_rate_id"] == $value) ? "checked=\"checked\"" : "";
  3. if (count($shipment) == 1 ) {
  4.         $checked = "checked=\"checked\"";
  5. }
  6. //$html .= '<label for="'.$shipping_rate_id.'">'."\n<input type=\"radio\" name=\"shipping_rate_id\" $checked value=\"$shipping_rate_id\" id=\"$shipping_rate_id\" />\n";
  7. $html .= "<input type=\"radio\" name=\"shipping_rate_id\" $checked value=\"$shipping_rate_id\" id=\"$shipping_rate_id\" />\n";
  8.  
  9. $_SESSION[$shipping_rate_id] = 1;
  10.  
  11. $html .= $value['ServiceName'].' ';
  12. $html .= "<strong>(".$value['TransportationCharges'].")</strong>";
  13. if (DEBUG) {
  14.         $html .= " - ".$VM_LANG->_('PHPSHOP_PRODUCT_FORM_WEIGHT').": ".$order_weight." ". $weight_measure.
  15.         ", ".$VM_LANG->_('PHPSHOP_RATE_FORM_VALUE').": [[".$charge_unrated."(".$fsc_rate.")]+".UPS_HANDLING_FEE."](".$taxrate.")]";
  16. }
  17. // DELIVERY QUOTE
  18. if (Show_Delivery_Days_Quote == 1) {
  19.         if( !empty($value['GuaranteedDaysToDelivery'])) {
  20.                 $html .= "&nbsp;&nbsp;-&nbsp;&nbsp;".$value['GuaranteedDaysToDelivery']." ".$VM_LANG->_('PHPSHOP_UPS_SHIPPING_GUARANTEED_DAYS');
  21.         }
  22. }
  23. if (Show_Delivery_ETA_Quote == 1) {
  24.         if( !empty($value['ScheduledDeliveryTime'])) {
  25.                 $html .= "&nbsp;(ETA:&nbsp;".$value['ScheduledDeliveryTime'].")";
  26.         }
  27. }
  28. if (Show_Delivery_Warning == 1 && !empty($value['RatedShipmentWarning'])) {
  29.         //$html .= "</label><br/>\n&nbsp;&nbsp;&nbsp;*&nbsp;<em>".$value['RatedShipmentWarning']."</em>\n";
  30.         $html .= "<br/>\n&nbsp;&nbsp;&nbsp;*&nbsp;<em>".$value['RatedShipmentWarning']."</em>\n";
  31. }
  32. $html .= "<br />\n";

User Friendly Design: Attachment Icons

Last October I helped launch www.psylabstudios.com, an online store for my friend Lars so he can hawk merch for his band Oneiroid Psychosis. This was my first foray into ecommerce, one that went pretty smoothly all things considered. We couldn’t use SSL, so we ended up using the Google Checkout API. I wrote a custom shopping cart for the site using the Google Checkout PHP library…

Anyway, I’m rambling. Fast forward 9 months to today. Lars emails me and asks for a way to create free items that are available for download. Things like computer wallpapers, screensavers and so on. I decided that the best way to accomplish this would be to add an “attachment” feature to store products. This way Lars could attach an arbitrary number of files to any product in the store.

The attachment plugin was fairly straightforward, since this is only an administrative feature. But I wanted it to make sure that users were clear on what exactly it was they were downloading.

I was initially going to use PHP’s mime_content_type() function to identify uploaded files, but it simply didn’t work (good thing it’s deprecated). Then I was going to use the finfo_file() function, but was unable to install PECL extensions on this particular site’s hosting environment. If you’re lucky enough to be running PHP 5.3.0, then finfo_file() is installed by default. No such luck here though.

Finally I decided to use a simple regular expression to scrape the file extension (like .jpg or .doc) from the file name. This is not a recommended way to do this, as it’s completely unreliable, but it’s better than nothing.

  1. <?php
  2.   preg_match('/\.([\w]{2,4}?)$/i', $filename, $matches);
  3.   echo $ext = $matches[1];
  4. ?>

The above regex will return $matches[1], which should be a 2 to 4 digit file extension (without the period). Now, the magic can happen!

Since we have a fairly good guess of what the filetype is, we can now assign a CSS class to the download link that will display an appropriate file icon. As an example, a video file will get a video icon, an MP3 will get a music icon and an Excel file will get a Microsoft Excel icon (see gallery below for examples). I’m using the Fugue icon set for this site (I know I’ve been pushing those icons a lot lately, but I’m just in love with them).

Finally, we can use the filesize() function to get the size of the file and display it to the user. This way they know what they’re getting into before they click download (helpful if they’re on a slow connection).

This may seem like a lot of work, but it really isn’t. It also greatly contributes to the overall experience of your site visitors. Plus it’s a lot of fun to write shiny web-applications.

UPDATE:

You can do this even easier using CSS selectors.

a[href$='.pdf'] {
  padding-left: 16px;
  background: url('icons/pdf.png') no-repeat left;
}

All this says is look for any anchor tag whose href value ends with “.pdf” and give it a background image. This is a super easy way to add context (and a little flair) for your site visitors.

PHP Session Data Lost Between [Some] Pages

frustrated

Ugh… So I’ve been working on a website for a student group at the University of Oregon. I’m developing a custom content management system for the site that uses jQuery UI and AJAX. It’s pretty spiffy actually.

Unfortunately I’ve always had problems maintaining $_SESSION data on the University web-server. For some reason my authentication class would work fine on my dev environment, but would randomly lose and then remember the $_SESSION data on the University web-server. This means that administrators would randomly get logged out when they were trying to update the site.

So after getting frustrated and avoiding the problem for several weeks, I finally found a solution here.

It turns out that the session.save_path value in php.ini was not set. The solution was to run session_save_path() at the top of my script and set the path manually to my home directory (one level below public_html).

<?php
  session_save_path('/home5/twadding/session_data/');
?>

This seems to have resolved the problem nicely. One caveat. Don’t keep your session data anywhere that is publicly accessible. Otherwise malicious users could access any of your session data on a whim.

Spending a week pouring over my code was incredibly frustrating, but at least my authentication class is nicely tuned now.

Thanks to turkguy0319 for the great image.