Posts Tagged ‘PHP’

Adding Location Awareness to Your Site

Friday, January 9th, 2009

I recently launched a new personal site.  I wanted to integrate some level of location awareness to it.  My initial design sketches called for the weather information and a position on a map of my last known location.

Initially, I was using a program on my iPhone called Loopt.  Loopt is like Twitter with location.  That involved jumping through hoops, as Loopt’s RSS feed only shows the GPS position of the last post.  Not only would I have to post a message every time I got somewhere, I’d have to reverse geocode my position to grab the zip code to send to get the weather information.  I achieved this through JavaScript with the Google Maps API.  This worked until I found out about Fire Eagle.

All Fire Eagle does is log your location. Luckily, Fire Eagle has an API. Eagle Feed turns your location into a publicly accessible RSS feed. So, getting your location is as easy as parsing an RSS feed. By setting the read level of Eagle Feed to my zip code, the title of the single item in the RSS feed reports my city, state, and zip (e.g. Birmingham, AL 35223), and my GPS coordinates are also in the feed.

You can update Fire Eagle by manually by entering your location on the site. However, there are mobile applications, such as Active Eagle on the iPhone, that use the GPS functionality of your device to update Fire Eagle. In Active Eagle, I simply tap “Update Fire Eagle” to update my location, and my Eagle Feed.

Once you can get your feed there are plenty of cool things you can do.

I wrote a simple PHP script to open my feed (or pull it from a cached file), grab the human-readable location from the title and parse out the zip code and my GPS position.

1
2
3
4
5
6
7
8
9
10
11
$out = file_get_contents($feed_url);
 
preg_match_all('/<title>(.*?)<\/title>/', $out, $loc_matches);
$human_loc = $loc_matches[1][1];
preg_match('/\d{5}/', $human_loc, $loc_matches);
$human_zip = $loc_matches[0];
 
preg_match('/<abbr class="latitude".*?>(.*?)<\/abbr>/', $out, $lat);
$loc_lat = $lat[1];
preg_match('/<abbr class="longitude".*?>(.*?)<\/abbr>/', $out, $long);
$loc_long = $long[1];

I then pass my zip code to Yahoo’s weather feeds to get weather data. I also pass my GPS position to Google Maps Static API to get a map of where I am.

Another idea would be to show Flickr photos in your area via the Flickr API. I’m sure there are tons of other things that would be fun or useful. Come up with some more ideas and make some cool stuff.

PHP Documentation Generators

Thursday, February 15th, 2007

I’ve been looking at documentation generators recently. Specifically, I’m playing with a new website that I want to do Right. Here are some notes for anyone looking at PHP documentation generators.

Languages

I needed a documentation generator primarily for PHP. However, I thought it’d be nice if it’d create documentation for JavaScript as well.

Possible Options

  1. PHPDocumentor

    Formerly called PHPDoc, PHPDocumentor was my first choice because I’ve heard of it before. It’s based on JavaDoc, and is conveniently packaged in PEAR. The syntax is a little weird at first, and documenting blocks of code inline doesn’t seem to be possible. However, it figures out a lot of useful stuff. PHPDocumentor, of course, doesn’t work with JavaScript. Despite the lacking feature, this is document generator I implemented.

  2. HeaderDoc

    HeaderDoc is Apple’s documentation system. It works with both PHP and JavaScript (as well as several other languages). I browsed the documentation, but haven’t bothered downloading the PERL code to compile it. I skipped on it because it seems far too robust (that is, bloated) for what I need and lacked some of the niceties of PHPDocumentor (e.g. detecting function names).

  3. Natural Docs

    I was really excited about Natural Docs when I first heard about it. The syntax seemed easy and it was supposed to understand inheritance, which would be a boon for JavaScript. Unfortunately, JavaScript and PHP are only supported insofar as they can be read in the document. No nifty features like they have with ActionScript, PERL, and C#. Too bad.

  4. Others

    I briefly looked at a few others that supported PHP and JavaScript. RoboDoc has fugly syntax and TwinText is supposedly Windows only (assuming it existed). Neither were going to be right for me.

PHPDocumentor in Use

Install

As I mentioned, PHPDocumentor is a PEAR package. That made the install very easy. I actually overcomplicated it quite a bit because of a few errors I had with the script. For future reference, you want to run pear install PHPDocumentor-beta since PHPDoc is depreciated. One will override the other.

As I said, when I tried to run phpdoc, I got an error about a file missing. Mac OS X apparently stores files in different places than the package expects. So, I had to edit the package and add chdir("/usr/lib/php/"); so that include("PhpDocumentor/phpDocumentor/phpdoc.inc"); would be run in the proper directory.

Since I wanted to have my documentation as a sub directory of my site, I had to write a shell script to clean out my documentation folder then run the PHPDocumentor command. Otherwise, PHPDocumentor would attempt to document the documentation.

Learning

I was a little bewildered by the syntax at first. This is mainly because it’s really hard to find solid examples of how to document code. The manual provides a little bit of instruction, but lacks real world examples. Luckily, I found a good example in the PEAR coding standards documentation. It wasn’t long until the syntax was second nature.

The only real gripe I have is that I’d like to be able to make inline comments about specific blocks of code. For example, a switch. It turns out that you have to do that within the function discussion. You can print code blocks in the discussion area, however. So, it’s almost as though you can do inline documentation.

I also should note that @var can only be attached to a class variable declaration, not any variable at all.

Output

I struggled with the output. I hate frames. So, I used the Smarty layouts for output at first. Eventually, I switched to the default frames layout because it handled some of the output better (e.g. unordered lists in discussions). Otherwise, it makes nice legible documentation that can be read on a web browser. It can also output PDF, and Windows Help files.

Final Opinions

PHPDocumentor is a pretty nice tool. Not only does it create documentation, it introduces a standard for commenting that is very legible. While I wish I cold have found a JavaScript and PHP document generator that I was happy with, PHPDocumentor does its job well.

Wikka Wiki Bread Crumbs

Friday, November 10th, 2006

Dan decided he wanted to set up a wiki to build content. I wasn’t involved in the process, but I got the job of making a bread crumbs script for the site.

Dan decided to use Wikka Wiki. When I asked why he didn’t use Media Wiki (the software that Wikipedia uses, which seems to be the de-facto standard), he said it required PHP 5, which our server doesn’t have. I guess that was a good-enough reason.

For all my niggles with Wikka Wiki, it is actually pretty standards compliant and has a cute name. The main issue with Wikka Wiki, which might be an issue with all wikis (I wouldn’t know since this is the first one I’ve ever coded on), is how it stores links from one page to another. It has a links table with a from_tag and to_tag. This is logical and works quite well until you try to do bread crumbs.

When you send a query to get every link that should go on a page, recursive links aren’t a problem. When you are trying to make a recursive function to get a bread crumb trail, it is quite annoying. Since Dan was in a hurry, he just did 10 left joins on the same table with a limit of one. That got the job done but didn’t always show a logical or short-route path to the current page. Dan decided that I was better at recursive functions and told me to work on it when I had time (except he calls them cookie crumbs instead of bread crumbs, which you’ll see in the code). After about 10 tries, I came up with the following:

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
function BuildCookieCrumbs2($page, $depth=0, $menu=array("CareerOpportunities","DefaultMenu","CurrentFrontPage")){
	if($depth &gt; 10)
		return;
	if(in_array($page,$menu)){
		return $page;
	}
	$sql = "SELECT to_tag, from_tag FROM career_opportunities_links WHERE from_tag IN ('".implode("','",$menu)."')";
	$r = $this-&gt;Query("SET NAMES UTF8");
	$r = $this-&gt;Query($sql);
	$o = array();
	$f = array();
	while($row = mysql_fetch_assoc($r)){
		$o[] = $row["to_tag"];
		$f[] = $row["from_tag"];
	}
	if($ret = array_search($page,$o)){
		return $f[$ret]."&gt;".$o[$ret];
	}
	else{
		$ret = "";
		$bcc = $this-&gt;BuildCookieCrumbs2($page,$depth+1,$o);
		$ret .= $bcc;
		$tmp = explode("&gt;",$ret);
		$sql = "SELECT FIND_IN_SET(from_tag,'".implode(",",$menu)."') as fis FROM career_opportunities_links WHERE from_tag IN ('".implode("','",$menu)."') AND to_tag = '".$tmp[0]."'";
		$r = $this-&gt;Query("SET NAMES UTF8");
		$r = $this-&gt;Query($sql);
		$row = mysql_fetch_assoc($r);
		$ret = $menu[$row["fis"]-1]."&gt;".$ret;
		if(in_array($page,$tmp)){
			return $ret;
		}
	}
	return $ret;
}
function BuildCookieCrumbs($page) {
	$ret = $this-&gt;BuildCookieCrumbs2($page);
	$ret = explode("&gt;",$ret);
	unset($ret[0]);
	return array_values($ret);
}

These two functions can be dropped into the Wakka.class.php file. I have no idea how to call it and put it into the template, as that part was already done when I started working on it. Sending the current page will return an array of tags to use in the bread crumb trail. You’ll probably want to change the default menu array in the BuildCookieCrumbs2, as it is set up to reflect our site.

This may not be the best solution, but it works pretty well.