Deprecated: Assigning the return value of new by reference is deprecated in /home/inh2ive/devtalk/wp-settings.php on line 472

Deprecated: Assigning the return value of new by reference is deprecated in /home/inh2ive/devtalk/wp-settings.php on line 487

Deprecated: Assigning the return value of new by reference is deprecated in /home/inh2ive/devtalk/wp-settings.php on line 494

Deprecated: Assigning the return value of new by reference is deprecated in /home/inh2ive/devtalk/wp-settings.php on line 530

Deprecated: Assigning the return value of new by reference is deprecated in /home/inh2ive/devtalk/wp-includes/cache.php on line 103

Deprecated: Assigning the return value of new by reference is deprecated in /home/inh2ive/devtalk/wp-includes/query.php on line 21

Deprecated: Assigning the return value of new by reference is deprecated in /home/inh2ive/devtalk/wp-includes/theme.php on line 623
DevTalk » 2008 » September

Sponsored links - alternative solution


Deprecated: Function split() is deprecated in /home/inh2ive/devtalk/wp-content/plugins/google-analytics-for-wordpress/googleanalytics.php on line 379

This time, we’ll do something a little bit different. I want to explain an idea based on a project.

The project was, in fact, a web directory for all the companies in my city. Each company had an image attached, and a link (besides the normal stuff, like name, phone number etc.). This was the basic package, meaning that a company could appear on the site for free. However, there was an option for customers which wanted to pay, in order to get their name faster to the users of the site… Because, really, this was the main idea to begin with.

So, besides the above-mentioned items, a paying company could add 3 photos more (like a small gallery), a wide description, and…oh yes, “sponsored link” treatment. What this means is that, if a user searches for something within the page, the first results would be the ones with a paid account. Pretty nifty, if I may say so myself.

And here is where the main discussion starts. How to go about implementing a sponsored links search system. As I’m sure you all are guessing there are many ways to do this, so I’ll only be talking about one.

For this, I used PHP, MySQL and a small bit of Javascript. We won’t focus so much on the first two, because it should be very easy implement a system that adds/modifies/removes items from a MySQL database using PHP for sending queries.

I will say that each item had a field to determine if it is sponsored or not, a simple, boolean (true/false) field. For the search system I used Sphider. It is a very nice search script, which crawls a site and then indexes the inner pages, based on keywords. Of course the tricky part was to modify the script in order to recognize the pages with a paid account. That means linking a search result with the MySQL database in order to determine its status.

With that out of the way, the only obstacle left was to display the sponsored links first. That was a challenge because the database didn’t make a difference between a paid and a free account (except for that certain field), and a “SELECT” query would return all the items regardless of their status.

And now, on to the final part of the story. For such a vast introduction, I know you would expect for an ending to match. But I have to say right from the start, that it’s a simple idea, but works really well in this situation. Sphider returns search results in the form of an array, which can be parsed in order to display the results. This was of great help, because each result can be manipulated individually. That means they can be styled or whatnot…but in this case they can be displayed as sponsored links, if that’s the case.

So, how do you display the sponsored links at the top of the page, even if they are at the bottom of the database? Easy:

You make a container <div> before the results and append the sponsored links to it. That way, they will be on top regardless of their previous order. Another simple but very effective concept. Unfortunately I can’t post any source code this time because I don’t have it anymore…but I have a small script which shows this concept:

<div id="div1" style="height:100px; width:300px; border:1px solid red;"></div>
<div id="div2" style="height:75px; width:250px; border:1px solid blue;"></div>

<script language="javascript">
var el1 = document.getElementById('div1');
var el2 = document.getElementById('div2');
el1.appendChild(el2)
</script>

That might not be much, but if you ever had to do something similar, I have no doubt this article was at least a little bit helpful. So, I hope you enjoyed reading this, because when I searched for some hints on this topic, I didn’t manage to find any out there.

Posted in: Javascript

PHP-XML selectors

We all know the getElementsByTagName function. However, wouldn’t it be nice to have a standard function for selecting elements based on an attribute value? Of course it would, but first we need to think about whether we need just the first element with the specific attribute, or all of them.

In the first case, things are pretty simple. All we do is use getElementsByTagName, which returns an array of elements with that specific tag name, and then we loop through it. In case we find an element with that certain attribute, we return it. If we don’t find any elements with that attribute value, we return NULL.

Here is the function:


function getElementByAttribute(DOMDocument $dom_xml,
 $tagname, $att_name, $att_value)
{
	$items = $dom_xml->getElementsByTagName($tagname);
	foreach($items as $item)
		if($item->getAttribute($att_name) == $att_value)
			return $item;
	return NULL;
}

Ok, pretty straightforward. We need to pass the xml handler(in case there are more than one), the tag name, the attribute name, then last and most important, the attribute value. This function returns a reference to that specific item in the xml file, so we can use all the functions associated with an xml item, like setAttribute, getAttribute etc.

Now, if we need all the elements which have the same attribute value, we have to write a function which stores them in an array and then returns it. I’ll say right from the start, I’m not really sure this is the best way to go about it, since this way you won’t be able to use the item(<index>) function, but the standard way for accessing items, array_name[<index>], works. So, it shouldn’t be too much of a problem. If you guys have any better ideas, please share them, they are very welcome.

So, on with the code:


function getElementsByAttribute(DOMDocument $dom_xml,
 $tagname, $att_name, $att_value)
{
	$array = array();
	$items = $dom_xml->getElementsByTagName($tagname);
	foreach($items as $item)
		if($item->getAttribute($att_name) == $att_value)
			array_push($array, $item);
	return $array;
}

That should do nicely. Function parameters have the same meaning as above.

Posted in: PHP

Equal height columns


Deprecated: Function split() is deprecated in /home/inh2ive/devtalk/wp-content/plugins/google-analytics-for-wordpress/googleanalytics.php on line 379

Deprecated: Function split() is deprecated in /home/inh2ive/devtalk/wp-content/plugins/google-analytics-for-wordpress/googleanalytics.php on line 379

There are many solutions out there regarding this old problem, of course, some better than others, and I had to try a come up with my own way of doing this. My question was how to set the height property of a div 100% of the container, which had the height set to auto. This could be used for the initial problem.

If we use Javascript, this can be very easily achieved.

First, let’s take a look at the mark-up:

<div id="container">
	<div id="column1">
	...
	</div>

	<div id="column2">
	...
	</div>
</div>

A standard container, with two child <div>’s. Now for the CSS:

#container
{
	width:402px;
	height:auto;
	overflow:auto;
	border:1px solid red;
}

#column1
{
	width:200px;
	height:auto;
	float:left;
	background-color:#00CC99;
}

#column2
{
	width:200px;
	height:auto;
	float:left;
	background-color:#0066FF;
}

Finally, we add a small script, just before the </body> tag:

<script language="javascript">
div1 = document.getElementById('column1');
div2 = document.getElementById('column2');

if(div1.offsetHeight > div2.offsetHeight)
	div2.style.height = div1.offsetHeight + 'px';
else
	div1.style.height = div2.offsetHeight + 'px';
</script>

The basic idea is to just set the height property of the smaller <div> equal to the taller one. Ok, that might not be the ultimate solution to this problem but it works if you need a quick way of rendering columns of equal height and you don’t want to use Faux columns.

You can see this little demo here.

Posted in: HTML/CSS

Finally…


Deprecated: Function split() is deprecated in /home/inh2ive/devtalk/wp-content/plugins/google-analytics-for-wordpress/googleanalytics.php on line 379

We all knew it was inevitable. It was just a matter a time, with no end in sight, however…but it’s finally here:

http://idroppedie6.com

Posted in: Uncategorized

XML array sorting using AJAX


Deprecated: Function split() is deprecated in /home/inh2ive/devtalk/wp-content/plugins/google-analytics-for-wordpress/googleanalytics.php on line 379

Deprecated: Function split() is deprecated in /home/inh2ive/devtalk/wp-content/plugins/google-analytics-for-wordpress/googleanalytics.php on line 379

Back again with a new post! This time, we’ll discuss how to make a sortable table using AJAX. This can be very useful when you make a site that displays items in the form of a list(table), and the user needs to sort the table using a specific criteria by clicking on a field.

In order to proceed, I’ll just mention a few things we need to know:

1. The list of items is stored in a XML file, therefore we’ll be loading the file using PHP.

2. In order to display the array without refreshing the page, we need to use XmlHttpObject so we can send a request to the server, in order to sort the array

3. The array isn’t sorted per say, we just need to retrieve a list of indices that defines the order of the items, in this case alpha-ascending order. This saves time because the server doesn’t need to do too many operations in order to sort the table.

You can see the project in action here.

Now that we have mentioned these things, we can proceed to analyze the project in detail.

1.

The XML file holds our list of items in the form of elements. Each element has three attributes which hold the value for that specific field. Since this is just a demo, I have used generic values:

<list>
  <item field1="Value 1" field2="Value 2" field3="Value 3"/>
  <item field1="Value 2" field2="Value 4" field3="Value 1"/>
  <item field1="Value 3" field2="Value 3" field3="Value 4"/>
  <item field1="Value 4" field2="Value 1" field3="Value 2"/>
</list>

Loading a XML file in a variable is simple enough using PHP 5:

$xml = new DomDocument(’1.0′);
$xml->preserveWhiteSpace = false;
$xml->load([ XML file ]);

And getting the items is also very simple:

$items = $xml->getElementsByTagName(’item’);

2.

Now that we have discussed the XML structure and the PHP-loading part, we can talk about how to use AJAX to sort the array using a request object and displaying the result.

The easiest way to create a request object is to use a function which returns an instance of the created object so you can store it in a variable, like this:


function GetXmlHttpObject()
{
	var xmlHttpObj = null;
	try
	{
		//Firefox, Opera8.0+, Safari
		xmlHttpObj = new XMLHttpRequest();
	}
	catch (e)
	{
		//Internet Explorer
		try
    		{
    			xmlHttpObj = new ActiveXObject("Msxml2.XMLHTTP");
    		}
		catch (e)
		{
			xmlHttpObj = new ActiveXObject("Microsoft.XMLHTTP");
		}
	}
	return xmlHttpObj;
}

The next step is to write the function which sends the request, and handles the response text. First we create a request object, then we form the string we want to send to the server, using the request, and finally, we write a function to determine if the request’s state has changed and therefore, a response is available. If the server has generated a response, another function handles the text. First the function to send the request:

function sendRequest(url, crit) //the url of the PHP script and the sorting criteria
{
	xmlhttpobj = GetXmlHttpObject(); //the above mentioned function

	if (xmlhttpobj == null)
	{
		alert ("Your browser does not support AJAX!");
		return;
	}

	var string = 'crit=' + crit; //string to send using the request

	xmlhttpobj.onreadystatechange = stateChanged;
	xmlhttpobj.open("POST", url, true); //we'll get the criteria using the $_POST variable
	//request headers
	xmlhttpobj.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
	xmlhttpobj.setRequestHeader("Content-length", string.length);
	xmlhttpobj.setRequestHeader("Connection", "close");

	xmlhttpobj.send(string);
}

Ok. This is the main function of our request sending script. Now, the only thing left, is to write the function which handles the server response upon the state change. This is again easy, since we only need to determine if the response has arrived. We do this by asking if the request’s ready state is 4, then we put the response text in a <div> element which has the id ‘container’:

function stateChanged()
{
    if (xmlhttpobj.readyState == 4) //global variable
        document.getElementById("container").innerHTML = xmlhttpobj.responseText;
}

3.

The final part of the application is the server-side script which handles the array sorting. Like I said in the beginning, we don’t actually need to sort the entire array, instead we just form an array of indices (corresponding to each item of the list) that defines the order in which we want to display the items, in this case, alpha-ascending order by one of the three fields. The algorithm loops through the items array and determines the index of the item with the minimal (alpha-ascending) that hasn’t been added to the index array. After one loop we get the index of the item that needs to be added at that particular moment, and after doing this for each item, we get an array that stores the indices of the items in alpha-ascending order.


function sort_xml(DOMDocument $s_xml, $att, &$array)
{
	$items = $s_xml->getElementsByTagName('item');
	$index = 0;
	$con = 0;

	for($i=0; $i<$items->length; $i++)
	{
		$con = 0;
		$min_att = 'zzzzzzzzzzzzzzzzzzzzzzzzzzzzzz';
		foreach($items as $item)
		{
			if(strcmp($item->getAttribute($att), $min_att) < 0 && !added($con, $array))
			{
				$min_att = $item->getAttribute($att);
				$index = $con;
			}
			$con++;

		}
		array_push($array, $index);
	}
}

The function which determines if an index has been already added:


function added($index, $array)
{
        for($i=0; $i<sizeof($array); $i++)
                if($array[$i] == $index)
                        return true;
        return false;
}

Now that we have a way to sort the array, the only thing left is to display the results according to the index array. First, we call the sort function:


$xml = new DomDocument('1.0');
$xml->preserveWhiteSpace = false;
$xml->load([ XML file ]);
$crit = $_POST['crit'];
$index_array = array();


sort_xml($xml, $crit, $index_array);

The we simply display the sorted table, since it will be handled as a response text:

<table>
	<tr bgcolor="#006699">
		<td width="100" onclick="sendRequest('scripts/table-script.php','field1')">
			<span class="heading">Field 1</span>
		</td>
		<td width="100" onclick="sendRequest('scripts/table-script.php','field2')">
			<span class="heading">Field 2</span>
		</td>
		<td width="100" onclick="sendRequest('scripts/table-script.php','field3')">
			<span class="heading">Field 3</span>
		</td>
	</tr>
	<?php
	$items = $xml->getElementsByTagName('item');
	for($i=0; $i<sizeof($index_array); $i++)
	{
		$item = $items->item($index_array[$i]);
		?>
		<tr bgcolor="#006699">
			<td><?php echo $item->getAttribute('field1');?></td>
			<td><?php echo $item->getAttribute('field2');?></td>
			<td><?php echo $item->getAttribute('field3');?></td>
		</tr>
		<?php
	}
	?>
</table>

We add the onclick attribute for all the field columns, and that’s it. Click here for a demo of this post.

Posted in: AJAX