Posts Tagged ‘PHP’

Export data as a CSV using PHP

Wednesday, February 10th, 2010

This is a very simple class for constructing basic comma-separated value (CSV) files in PHP. The export method forces the correct headers to initiate a file download. More information can be had in the PHP documentation.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<?php
 
	class CSV {
		protected $data;
 
		/*
		 * @params array $columns
		 * @returns void
		 */
		public function __construct($columns) {
			$this->data = '"' . implode('","', $columns) . '"' . "\n";
		}
		/*
		 * @params array $row
		 * @returns void
		 */
		public function addRow($row) {
			$this->data .= '"' . implode('","', $row) . '"' . "\n";
		}
		/*
		 * @returns void
		 */
		public function export($filename) {
			header('Content-type: application/csv');
			header('Content-Disposition: attachment; filename="' . $filename . '.csv"');
 
			echo $this->data;
			die();
		}
		public function __toString() {
			return $this->data;
		}
	}
 
	$csv = new CSV(array('date', 'name', 'address'));
	$csv->addRow(array('2/2/2010', 'John', 'Portland, OR'));
 
        // export csv as a download
	$csv->export('names.csv');
 
        // pass the csv data to a variable as a string
        $string = $csv;
 
?>

Create and list new tickets through the Assembla API

Friday, October 23rd, 2009

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

Wednesday, August 19th, 2009

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.

356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
$shipping_rate_id = urlencode(__CLASS__."|UPS|".$value['ServiceName']."|".$charge);
$checked = (@$d["shipping_rate_id"] == $value) ? "checked=\"checked\"" : "";
if (count($shipment) == 1 ) {
        $checked = "checked=\"checked\"";
}
//$html .= '<label for="'.$shipping_rate_id.'">'."\n<input type=\"radio\" name=\"shipping_rate_id\" $checked value=\"$shipping_rate_id\" id=\"$shipping_rate_id\" />\n";
$html .= "<input type=\"radio\" name=\"shipping_rate_id\" $checked value=\"$shipping_rate_id\" id=\"$shipping_rate_id\" />\n";
 
$_SESSION[$shipping_rate_id] = 1;
 
$html .= $value['ServiceName'].' ';
$html .= "<strong>(".$value['TransportationCharges'].")</strong>";
if (DEBUG) {
        $html .= " - ".$VM_LANG->_('PHPSHOP_PRODUCT_FORM_WEIGHT').": ".$order_weight." ". $weight_measure.
        ", ".$VM_LANG->_('PHPSHOP_RATE_FORM_VALUE').": [[".$charge_unrated."(".$fsc_rate.")]+".UPS_HANDLING_FEE."](".$taxrate.")]";
}
// DELIVERY QUOTE
if (Show_Delivery_Days_Quote == 1) {
        if( !empty($value['GuaranteedDaysToDelivery'])) {
                $html .= "&nbsp;&nbsp;-&nbsp;&nbsp;".$value['GuaranteedDaysToDelivery']." ".$VM_LANG->_('PHPSHOP_UPS_SHIPPING_GUARANTEED_DAYS');
        }
}
if (Show_Delivery_ETA_Quote == 1) {
        if( !empty($value['ScheduledDeliveryTime'])) {
                $html .= "&nbsp;(ETA:&nbsp;".$value['ScheduledDeliveryTime'].")";
        }
}
if (Show_Delivery_Warning == 1 && !empty($value['RatedShipmentWarning'])) {
        //$html .= "</label><br/>\n&nbsp;&nbsp;&nbsp;*&nbsp;<em>".$value['RatedShipmentWarning']."</em>\n";
        $html .= "<br/>\n&nbsp;&nbsp;&nbsp;*&nbsp;<em>".$value['RatedShipmentWarning']."</em>\n";
}
$html .= "<br />\n";

User Friendly Design: Attachment Icons

Tuesday, July 7th, 2009

psylabs-attachments

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

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.

PHP Session Data Lost Between [Some] Pages

Monday, February 2nd, 2009

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.