My Blog

contains PHP and other web related content. (Sometimes there are some off topic things - don't freak out!)

XFN – XHTML Friends Network

February 5th, 2010

While I continue to look at the semantic web, I can’t help but scratch my head and say “why” about some of these technologies. I feel like its still sadly lacking… with that, let me introduce…

XHTML Friends Network

XFN (website here) aims to build relationships between people on the internet using specific attribute values in the link tags. Once again, this particular method has a list of types of relationships that can be applied to build an N-N relationship.

Should I use it?

I myself am not planning on using it (well… yet). Most of my websites are not strongly ‘friend’ oriented. Instead, they are content based. There are some relationships built on pages like the JEMDiary friends page… but nothing too extreme.

Should you use it? Well… maybe.

Its kind of niche

One of the biggest ‘arguments’ for the implementation of XFN has been the ‘blog-roll’ instances on the sides of blogs. Blogs themselves are not niche – but this ‘friends list’ kind of is. I think only a small portion of users actually keep an updated blog-roll. Blogs are so widespread – especially now with media company based and editorial blogs – that keeping a ‘friends list’ would be nearly impossible. So that niche is dying.

Another large portion of the web is social networking. However, I still believe the implementation of XFN in a social networking site is a niche possibility. One of the biggest debates right now centers around the security changes on facebook. They have decided to push more information to the public internet which is causing quite a ruckus. The main point of XFN is to provide relationships to the public. So, if this protocol must be consumed, this information must be public, and must be implemented in a way that the user who is demonstrating their relationships agrees with. A questionable niche.

So, should you implement it? Hrm…

Users Must Be Disciplined

If you’re not the author of the XFN, your users may be. This means that they have to share the same discipline and understanding of the concept as you do. Take these three specific values for the attribute: “friend, met, colleague.” When you finally study the specification, it makes sense. However, the likeliness of some user specifying their relationship incorrectly with XFN without having read the instructions is great.

It probably doesn’t hurt

Except for the reason stated above (users may mis-label their relationships), there is only one scenario that I can see where I can see a problem: the potential for two sources to list different information about a relationship. But besides that, I look at XFN as sort of an after thought. I may implement it on some of my social network based sites – but very sparsely.

Your thoughts?

hCard – should I care?

January 23rd, 2010

So lately, I’ve been looking into the semantic tools available on the web. I want to make sure that my online identity is easily searchable and undeniably accurate. Using semantic tools such as XFN, FOAF and hCard may help me.

I can’t help but seeing some of these and thinking ‘flash in the pan’ though. What I really want to see is a big – or a giant – company come through and make use of these. For example, LiveJournal is exporting FOAF information – but who cares? Where can I actually find value out of that information that was previously consumed? If I search ‘Aaron Saray’ on Google, will my friends show up along the sidebar?

At any rate, I did implement a very basic FOAF RDF file on my home page. I am reluctant to do anything further, however. Like I said, I’m not seeing much value as of yet. However, I did want to look at another alternative, hCard.

What is hCard

hCard is just an expansion on the vCard standard. The website says it has a 1:1 representation of the vCard properties. Plus, it goes further by allowing itself to be embedded into web properties. So basically, its a vCard that I show on my website, right? Isn’t this already what my contact page does? (Yes – but the argument is this is a standardized form so that it can be machine readable – I get it I get it).

Who is using hCard

More and more libraries are using hCard. The number one thing that caught my eye was the possible implementation by drupal (see http://groups.drupal.org/node/1898. Yet, I’m seeing many people put out the information to be consumed, but I’m not seeing many groups actually doing the consuming.

How can I use it?

Well besides looking at the specs, you can use the following two libraries in PHP:
phpMicroformats
Microformats Parser

So what did you do?

Ok so after all this complaining, I have to admit – I’m still guilty… I implemented it on my contact page :)

Friend of a Friend: FOAF

January 20th, 2010

So I added my own FOAF link on my home page. The RDF file is here:
http://assets.aaronsaray.com/assets/foaf.rdf

For those who aren’t familiar, Friend of a Friend is a protocol defined to help machines read relationships between entities (persons) on the internet. The relationships are set up in RDF file. (Mine is severely limited – either I have no friends – or am just lazy – you tell me!) For more info, check out http://www.foaf-project.org/.

By far, the best library I’ve found for parsing FOAF files is located here: http://gna.org/projects/phoaf

Making Friendly Javascript Errors – Client and Server

January 14th, 2010

The more I look at my code I wrote in my earlier posts about the unknown _popupControl() function and the Javascript Error Handler, I see opportunities to leverage these errors into useful user interactions.

Doing a service for your visitor

After your javascript is tried and tested and error free, there are still chances that errors can be logged using my utility. These usually are the result of Spyware that is left on the user’s machine. Sometimes some removal processes don’t capture all of it. The _popupControl() method was one such remnant.

I thought that instead of just ignoring these issues, I could gently alert the user to the issue. Perhaps, I could even get affiliate commissions for a product that I know for sure removes these threats.

There are two ways to go about handling these javascript errors: client side and server side.

Client Side

Client side javascript error handling requires a bit more front-end programming. It also shows a lot of your cards to the outside world. By looking at the code in the javascript portion of your page, visitors could see all types of errors that you’re trying to detect. While I don’t think this is a deterrent to using this method, you may feel otherwise.

First things first – if you can’t remember, check out my Javascript Error Handler and Logger entry to see the code I’ll be expanding on.

My new code is going to look something like this:

?View Code JAVASCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
            window.onerror = function (message, url, line) {
                /** log message **/
                var i = new Image();
                i.src = 'error.php?url=' + escape(url) + '&message=' + escape(message) + '&line=' + line;
 
                if (message.indexOf('spywareWindowGenerator')) {
                    var d = document.createElement('div');
                    d.innerHTML = 'Sounds like you got spyware';
                    document.body.appendChild(d);
                }
                else if (message.indexOf('otherbaddie')) {
                    var d = document.createElement('div');
                    d.innerHTML = 'Sounds like you got some other baddie';
                    document.body.appendChild(d);
                }
            }

I’ll break it down:

First, the standard logging service is initiated on error. The error.php file will log the javascript error for further research later.

Next, I evaluate the actual message that was sent to the error handler. In this example, I’m looking for two possible issues, a reference to the function _spywareWindowGenerator() and a reference to someOtherBaddie(). Both of these functions are not defined in my code and can be considered to be remnants of the spyware infestation.

The first ‘if’ statement checks for the existence of ’spywareWindowGenerator’ in the message. If it exists, it creates a new DIV HTML element. Then, it populates it with a message regarding this error. (Note, you could also load an image, create link, etc.). Finally, just for demonstration purpose, that DIV is added to the end of the body and is displayed.

The second if statement is simply checking for the case of ‘otherBaddie’ – and will do a similar process.

Like I mentioned before, this lays all of your cards out on the table – could potentially make your page load longer (especially if you have a lot of spyware you’re tracking), but be most versatile.

Server Side

With server side, I’m going to rely on the image that the javascript error handler is loading. If this image is populated by my error.php file, then I’ll show it.

First, the modified javascript for our error handler now looks like this:

?View Code JAVASCRIPT
1
2
3
4
5
6
7
8
9
10
11
            window.onerror = function (message, url, line) {
                /** log message **/
                var i = new Image();
                i.src = 'error.php?url=' + escape(url) + '&message=' + escape(message) + '&line=' + line;
 
                /** now check to see if we have something to show **/
                if (i.height) {
                    /** add it to the page **/
                    document.body.appendChild(i);
                }
            }

The first part is the standard logging mechanism that we’re used to. However, after that, I check for a height of the image that was requested. If no image was generated by the PHP GET request, then the height will be 0. Otherwise, the image object will return a height. Then, just for demonstration, I append that image to the bottom of the body of the document.

This means that we put a little bit more of the responsibility for determining the message to display to the user on the back end. At first it seems like it could be a little less verbose – as it is just an image. However, we could expand the javascript error handler to detect what ‘link’ it could display based on the image dimensions, etc. (This is for a different entry if need be…)

Next, I had to edit my error.php file. It now contains this code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$keys = array();
$keys['_spywareWindowGenerator'] = 'badSypware.png';
$keys['otherBadGuy'] = 'otherBadGuy.png';
 
/**
 * check for an image to show
 */
 
$imageToShow = '';
foreach ($keys as $substring=>$image) {
    if (stripos($_GET['message'], $substring) !== false) {
        $imageToShow = $image;
    }
}
 
if (!empty($imageToShow)) {
    header('Content-Type: image/png');
    readfile($imageToShow);
    die();
}
else {
    error_log("{$_GET['message']} occured on line {$_GET['line']} of URL {$_GET['url']}");
}

The first step is to determine all of the key words that could appear in javascript error messages. Then, associate them with an image that conveys our message.

The next bit of code looks through and searches the message for any of the possibilities. If it finds one, it sets the image to be the associated value for that key.

Finally, the PHP code checks to see if there is an image to show. If so, it sends the proper header and reads the file to the output buffer. Otherwise, it assumes it is an error that we’re not familiar with and logs it.

In this example, I used the following two images just for testing.

Using Google Analytics Asynchronously

January 11th, 2010

I came across the following link on google’s code pages:
http://code.google.com/apis/analytics/docs/tracking/asyncTracking.html

It basically details the asynchronous loading of google analytics. I found this to be a very cool addition to an already powerful package that I rely on.

However, one thing that I haven’t been able to successfully figure out. What happens when you want to load in two instances or two different accounts? On one of my sites, I use my own google analytics account plus the clients. This tracks the traffic fine with the non-asynchronous method. You simply make a new instance of the ga object and assign a new ID to it. However, can I do the same thing with this asynch method? I’m kind of wary to try it because I don’t want to lose any data.

Anyone have any experience or have any links to where I can find this detail?

document.URL vs document.location.href

December 18th, 2009

When reviewing some javascript security ideas, I came across the document.URL property. Turns out that my normal way of retrieving the location (document.location.href) is both a getter and a setter. The document.URL is just a getter.

Check it out with this code:

?View Code JAVASCRIPT
1
2
3
4
alert(document.URL);
alert(document.location.href);
document.URL = 'http://google.com';
document.location.href = 'http://yahoo.com';

The results are simple: you will get the current location twice – and then an error. If you comment out the document.URL line, it will redirect to yahoo.

Protect Your Image from Download

December 16th, 2009

I came across a great idea dealing with protecting image downloads from the site. Now, this is not fool-proof. There are lots of other ways to download the image, but this may stop the casual downloader. Nope, its not disabling the right click or using java. It requires one single transparent gif. Let’s see how.

Read the rest of this entry »

Javascript Snow Fall with buildup

December 6th, 2009

Mr. Skowron (his business) was working on a flash animation for a client that had a snow fall. What really irked me about the end result, was two things.
a) it was in flash
b) the snow didn’t build up

The client was happy. So that’s all good. But, I like a challenge… So I decided to make my own version.

The Snowfall Script

I didn’t want to reinvent the wheel – so I grabbed a pre-made script (by Scott Schiller). It simply adds the snowfall to the body.

Creating a snow line

The next thing I wanted to do was make a snow line that would slowly creep up. My first thought was just to have a standard white swoosh move up. This wouldn’t work because I wanted to have it scale the entire size of the monitor. Plus it wouldn’t look that natural.

I decided to make three images with various swoosh type marks about 500px wide. Then, I used photoshop to offset them by half. (Filter -> Other ->offset -> set horizontal to 1/2 the width of the image). This made the image tile-able. (It may be necessary to smooth out the new overlap you just created). All three were created, 500px wide and 50px tall.

Creating the HTML

The HTML would be pretty simple. I had to have three snow lines – oh and I wanted a tree. Let’s take a look:

1
2
3
4
5
6
7
8
9
10
11
12
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
    <head>
        <title>Snow!</title>
    </head>
    <body>
        <div id="tree"></div>
        <div id="snow1" class="snowblock"><div></div></div>
        <div id="snow2" class="snowblock"><div></div></div>
        <div id="snow3" class="snowblock"><div></div></div>
    </body>
</html>

We’ll be referring to these elements a little bit later.

Use CSS to Position Everything

The next thing to do was to give my div’s some dimension and some background images. I thought I’d start out each snow line 50px from the bottom and tile the image. Since they have transparent edges, you should be able to see varying lines of ‘horizon’ on the snow. I also placed the tree image near the right edge to give it that look I was looking for.

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
            body {
                height: 100%;
                padding: 0px;
                margin: 0px;
                background: #000;
            }
            #tree {
                background: url('treeback.jpg') no-repeat;
                position: absolute;
                bottom: 10px;
                right: 20px;
                height: 396px;
                width: 530px;
            }
            .snowblock {
                position: absolute;
                bottom: 0px;
                width: 100%;
                background-repeat: repeat-x;
                height: 40px;
            }
            .snowblock div {
                background-color: #fff;
                margin-top: 40px;
                height: 0px;
            }            
            #snow1 {
                background-image: url('snow1.png');
            }
            #snow2 {
                background-image: url('snow2.png');
            }
            #snow3 {
                background-image: url('snow3.png');
            }

First, give the body some background color, get rid of paddings and set a height of 100%. The next section is the tree placement. This is pretty simple.

For each class of snowblock, they are absolutely positioned at the bottom with 100% width. I gave them each 40px height. Each image is 50px tall, but I wanted an acceptable gutter just in case.

As each image moves up, they will start to reveal the background color again. To solve this, the interior divs are given a background color of white. Their top margin is 40px – to offset them enough from the image (so as to not bleed their own background color upwards into the transparent snowline). They start out with no height.

Finally, each image div is given a background image of snow.

The magical javascript

First off, I put the following javascript include tags in the HTML

1
2
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
        <script type="text/javascript" src="snowstorm.js"></script>

After loading jquery and the premade script, the following javascript is executed:

?View Code JAVASCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
        function upSnow()
        {
            var id = 'snow' + (Math.floor(Math.random()*3) + 1);
            var snow = $("#"+id);
            var filler = $("#" + id + " div");
            snow.height(snow.height() + 1);
            filler.height(filler.height() + 1);
        }
 
        $(function(){
            snowStorm.flakesMax = 250;
            snowStorm.flakesMaxActive = 100;
            snowStorm.animationInterval = 33;
            snowStorm.snowStick = false;
            setTimeout(function(){setInterval('upSnow()', 2000)}, 5000);
        });

First, the upSnow() function is generated. This will randomly pick an ID between snow1 and snow3 and inch it up 1px. The child div’s height is also increased by 1 pixel.

When the javascript fires, a few options are set for the snowStorm js library.

Finally, a timeout and an interval are set. The first timeout is used to set the interval. I don’t want the interval to start until the first flakes start hitting the ground. this takes approximately 5 seconds, so that delay is set.

After 5 seconds, the anonymous function fires off the setInterval request to run the upSnow() function every two seconds.

See it in Action

Seems to me, people like to SEE this stuff in action. Weird. Anyway, here ya go:
http://demo.aaronsaray.com/demo/snow/

Auto Failover for CDN based Javascript

November 30th, 2009

Using my javascript error reporter code helps me get a better understanding of what my clients are experiencing when visiting my website. One thing I did notice was the failures from time to time of Google’s CDN based Jquery.

To solve this issue, I decided to keep a local copy as well. For the most part, Google’s version is going to be faster and have a better cache method. However, I’d rather have an uncached version of it loaded into the user’s browser than nothing at all! So, in the very rare case that the user’s browser fails to load the Google javascript, I load a local copy of it.

First Step: Load JQuery From Google

The very first thing I do is to include jQuery from google’s code base using the following tag:

1
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>

This will retrieve the latest version (1.3.2) from Google with the proper compression and cache response I like.

However, this sometimes was failing – well according to my error reporting script. What to do?

Test for a successful load of jQuery

Since the SCRIPT tag does not have an ‘onerror’ standard notifier like our image, the next best thing to do is test for the jQuery object right after the page loads. Since we’re using inline javascript, the first request to the external javascript will block while loading. When it completes, this small snippet will then execute.

I’ll jump ahead one more step though before code.

If no jQuery found, load it dynamically

If the jQuery object is not found, a new script element is created dynamically. The source is pointed to my local version of the script. Finally, it is appended to the head. Hopefully this will load the jquery. If it fails here, well then – the client has some issues!

This is the full inline javascript after the external javascript reference:

?View Code JAVASCRIPT
1
2
3
4
5
6
if (typeof jQuery == 'undefined') {
	var e = document.createElement('script');
	e.src = '/js/noncdn-jquery-1.3.2.js';
	e.type='text/javascript';
	document.getElementsByTagName("head")[0].appendChild(e);
}

In this case, the path http://mydomain.com/js/noncdn-jquery-1.3.2.js contains my local javascript.

The results?

Before this fix, I saw a failed jQuery load about once a day. I have not seen a single one yet. I have yet to see this error reported. If anyone finds a better way to do this, please let me know!

Block and Allow IP with iptables – simple script

November 25th, 2009

As most developers are lazy, I’m a huge fan of scripts. I’ve found myself lately having to add entries to iptables to block a single IP or a small subnet, so I made a quick script to make the job easier on myself.

Usage for both of these is of course really simple. Say 123.1.2.3 is the IP in question:

sudo ./blockip.sh 123.1.2.3
sudo ./allowip.sh 123.1.2.3

blockip.sh
Blocks the IP using iptables

1
2
3
4
5
6
7
#!/bin/bash
 
#blocking iptables
/sbin/iptables -A INPUT -s $1 -j DROP
 
#saving iptables
/sbin/iptables-save > /etc/sysconfig/iptables

allowip.sh
Removes the entry from iptables

1
2
3
4
5
6
7
#!/bin/bash
 
#allowing iptables
/sbin/iptables -D INPUT -s $1 -j DROP
 
#saving iptables
/sbin/iptables-save > /etc/sysconfig/iptables
  • twitter loader

Follow me on twitter: @aaronsaray

The views on this website are my own and do not reflect the opinions of my employer or clients.
Creative Commons License Home | Open Source | Book | Music | Art | Bio | Resume | Contact
My Baby