Monthly Archive for January, 2009

Parse CSV File

I’m using wp-table for a Wordpress project, and you can read in data from a csv file and it builds a table for you. At least, that’s the theory. In fact, it uses PHP’s built-in fgetcsv() function. Which blows.

fgetcsv() does a good job of parsing lines which are comma separated values, but it’s really profoundly retarded about understanding that the end of a line is the end of a record. If you read in 1000 bytes, you could have 10 records/line in there, but it mashes them all into one array.

So I wrote my own. It’s pretty basic, but it works.

function parse_csv_file($file, $columnheadings = false, $delimiter = ';', $enclosure = '"') {
 
	$row = 1;
	$rows = array();
 
	$file_contents = file_get_contents($file);
 
	// determine the line break character sequence
	$line_break = chr(13) . chr(10);
	$pos = strpos($file_contents, $line_break);
	if ($pos === false) { // didn't find that
		$line_break = chr(10);
		$pos = strpos($file_contents, $line_break);
		if ($pos === false) { // not that either
			$line_break = chr(13);
			$pos = strpos($file_contents, $line_break);
			if ($pos === false) { // uh oh
				// Cannot determine line break character sequence.
				exit;
			} else {
				// Line breaks on 13
			}
		} else {
			// Line breaks on 10
		}
	} else {
		// Line breaks on 13.10
	}
 
	$lines = split($line_break, file_get_contents($file));
	foreach ($lines as $line_num => $line) {
		$line = trim($line);
		if ($line == '') continue;
 
		$l = array();
		$enc = false;
		$v = '';
		for ($i = 0; $i < strlen($line); $i++) {
 
			$char = substr($line, $i, 1);
 
			if ($char == $enclosure) {
 
				if ($enc) {
					$enc = false;
				} else {
					$enc = true;
				}
 
			} else if ($char == $delimiter) {
 
				if ($enc) {
					$v .= $char;
				} else {
					$l[] = $v;
					$v = '';
				}
 
			} else {
				$v .= $char;
			}
 
		} // end foreach character in this line
 
		$rows[] = $l;
	}
 
	return $rows;
}

Show/Hide CSS For Three Levels Of Menu/Nav

Written with wordpress in mind, but you can adapt as necessary.

Often you have levels of pages. You’ll have top level pages, and some of them have child pages, and some of those child pages have grandchild pages. Usually what you want is for the menu/navigation/sidebar to limit what it’s displaying. You don’t want to see everything, only what’s under where you are now in the hierarchy.

Default case:
ONE
TWO
THREE
Case 2:
ONE (current page item)
- CHILDA
- CHILDB
- CHILDC
TWO
THREE
Case 3:
ONE (current page parent, current page ancestor)
- CHILDA (current page item)
- - GRANDCHILD
- CHILDB
- CHILDC
TWO
THREE
Case 4
ONE (current page ancestor)
- CHILDA (current page parent)
- - GRANDCHILD (current page item)
- CHILDB
- CHILDC
TWO
THREE

Alright, so here’s the CSS to make this happen:

#menu ul li ul {
	display: none;
}
#menu ul li.current_page_ancestor ul {
	display: block;
}
#menu ul li.current_page_ancestor ul li ul {
	display: none;
}
#menu ul li.current_page_ancestor ul li.current_page_parent ul {
	display: block;
}
#menu ul li.current_page_parent ul li.current_page_item ul {
	display: block;
}
#menu ul li.current_page_parent ul li.current_page_item ul li ul {
	display: none;
}
#menu ul li.current_page_item ul {
	display: block;
}
#menu ul li.current_page_item ul li ul {
	display: none;
}