<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="wordpress/2.3.3" -->
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	>

<channel>
	<title>pr0digy.com</title>
	<link>http://pr0digy.com</link>
	<description>Web development with CodeIgniter and Mootools.</description>
	<pubDate>Tue, 24 Jun 2008 08:47:04 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.3.3</generator>
	<language>en</language>
			<item>
		<title>CodeIgniter for Rapid PHP Application development</title>
		<link>http://pr0digy.com/codeigniter/codeigniter-for-rapid-php-application-development/</link>
		<comments>http://pr0digy.com/codeigniter/codeigniter-for-rapid-php-application-development/#comments</comments>
		<pubDate>Fri, 30 May 2008 10:10:38 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
		
		<category><![CDATA[books]]></category>

		<category><![CDATA[codeigniter]]></category>

		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://pr0digy.com/codeigniter/codeigniter-for-rapid-php-application-development/</guid>
		<description><![CDATA[This 241 page book is written by David Upton, published by Packt and available in both paper and electronic versions - I&#8217;ll be reviewing the later one.  This book is based on CodeIgniter 1.5.3, but should work just fine with the current version (1.6.2), as no dramatic changes were introduced up to this point.
Brief [...]]]></description>
			<content:encoded><![CDATA[<p>This 241 page book is written by David Upton, published by Packt and available in both paper and electronic versions - I&#8217;ll be reviewing the later one.  This book is based on CodeIgniter 1.5.3, but should work just fine with the current version (1.6.2), as no dramatic changes were introduced up to this point.</p>
<h3>Brief summary by chapter</h3>
<p>The 1st chapter is pretty much for novice users, who may not be familiar with frameworks.  In this chapter one will find some fundamental information about frameworks in general, followed by a brief introduction to CodeIgniter.</p>
<p>The 2nd chapter goes through the installation procedure, file and directory structure and some basic configuration.  I feel that this chapter lacks the info on how to set up a site using mod_rewrite (without index.php part in URL) - many newcomers are asking how to do this on the official forums, over and over, yet it&#8217;s not properly documented.</p>
<p>The 3rd chapter contains some essential information about MVC and how that pattern is realized in CodeIngiter.  This chapter explains how to use controllers and access their methods (routing basics), as well as how to use views, models, libraries and helpers.</p>
<p>Starting with chapter 4 the book goes into specific areas of CodeIgniter.  The 4th chapter shows how to utilize CI&#8217;s Database and Active Record libraries.  Here you will find how to set up a DB connection, how to manipulate the data (plenty of examples are included), as well as a full set of SQL statements for a practice DB.</p>
<p>The 5th chapter, primarily, focuses on views.  Here you will find out how to assign data to views and then render the result in various ways, as well as how to use multiple/nested views.  Also, there is a quick intro to CodeIgniter&#8217;s validation library.  The most interesting thing in this chapter, in my opinion, is the custom display model, which can save you quite a bit of time and hassle.</p>
<p>The 6th chapter mainly covers CodeIgniter&#8217;s security aspects.  Here you will find how to securely authenticate a user and process, store and pass session data.<br />
Chapter 7 gives a quick intro to OOP, then jumps into the inner workings of the framework itself (which is OOP based, of course).  Here you will find a thorough explanation of CodeIngiter&#8217;s object model.  Those working in PHP5, however, should note that all objects are already passed by reference.</p>
<p>The 8th chapter covers error logging and handling, unit test library, benchmarking class, and profiler feature.  All of the above features are extremely helpful - this chapter can save you a lot of time in tracking and squashing bugs.</p>
<p>Chapter 9 covers FTP, XML-RPC and Email libraries.   While you are not likely to use the first two very often, the Email class will come very handy in just about any application.</p>
<p>Chapter 10 has an odd and rather misleading name - &#8220;How CI helps to Provide Dynamic Information&#8221; - the chapter, in fact, discusses and odd collection of features that are not much related to each other.  Here you will find info about date and text helpers, HTML table class, an odd implementation of internalization (the Language class) and finally the caching feature.  My guess is that the name should have been - &#8220;Simplifying work with dynamic template data&#8221; - something like that :)</p>
<p>Chapter 11 focuses on libraries that deal with file operations.  The following features are discussed: file and download helpers, upload and file compression classes, as well as image processing library.  If you want to create a web gallery or a similar application, then this chapter is for you :)</p>
<p>The 12th chapter discusses various issues that may occur when migrating your application to a production server.  You will also find out how to upgrade CodeIgniter to a newer version, as well as extending already existing functionality of core libraries.</p>
<p>Chapter 13 talks about CRUD.  In my own experience, CodeIgniter&#8217;s built in CRUD is not very useful.  However, you may find some extensions, mentioned in the final chapter, to make this feature more useful.</p>
<p>The 14th chapter weighs out pros and cones.  Here the author outlines where the framework was useful and where it could use some improvement.  Personally, I don&#8217;t think that CodeIgniter needs an AJAX class.  I do, however, think that validation and internationalization could be greatly improved and generic authorization wouldn&#8217;t hurt either.</p>
<p>In the final chapter, the author speaks of additional external resources, which may simplify your life even further.  Essentially, there are references to forums, wiki, some video tutorials, some libraries, and some AJAX/JavaScript stuff.  From myself, I&#8217;d like to add the official video tutorials (I found them most helpful), as well as the official documentation.  I don&#8217;t, however, recommend any of the mentioned AJAX resources, as they use an obtrusive approach and there are much better ways of integrating JavaScript into CodeIgniter.</p>
<h3>Conclusion</h3>
<p>If you are an advanced CodeIgniter user, this book won&#8217;t do much for you, in my opinion.  There aren&#8217;t many advanced topics, nor there are any PHP5 specific discussions.  However, if you are new to CodeIgniter, then this book is definitely worth reading.  Generally, it&#8217;s straightforward, but most importantly easy to digest.  With this book, you will be able to quickly figure out what exactly CodeIgniter is, and how to efficiently utilize it for your projects.</p>
]]></content:encoded>
			<wfw:commentRss>http://pr0digy.com/codeigniter/codeigniter-for-rapid-php-application-development/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Performance benchmark: Cake vs. CodeIgniter vs. Kohana</title>
		<link>http://pr0digy.com/codeigniter/benchmark-static-cake-codeigniter-kohana/</link>
		<comments>http://pr0digy.com/codeigniter/benchmark-static-cake-codeigniter-kohana/#comments</comments>
		<pubDate>Fri, 09 May 2008 11:31:05 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
		
		<category><![CDATA[codeigniter]]></category>

		<category><![CDATA[frameworks]]></category>

		<category><![CDATA[kohana]]></category>

		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://pr0digy.com/codeigniter/benchmark-static-cake-codeigniter-kohana/</guid>
		<description><![CDATA[The setup
This benchmark measures &#8216;out of the box&#8217; performance of the above 3 frameworks.  Framework versions are as follows: Cake 1.2.0.6311-beta, CodeIgniter 1.6.1, Kohana 2.1.1 (latest stable releases available at the time of testing).  For this test I used a small static &#8216;hello world&#8217; page, no dynamic elements other than framework internals.  [...]]]></description>
			<content:encoded><![CDATA[<h3>The setup</h3>
<p>This benchmark measures &#8216;out of the box&#8217; performance of the above 3 frameworks.  Framework versions are as follows: Cake 1.2.0.6311-beta, CodeIgniter 1.6.1, Kohana 2.1.1 (latest stable releases available at the time of testing).  For this test I used a small static &#8216;hello world&#8217; page, no dynamic elements other than framework internals.  I chose not to use frameworks&#8217; built in caching engines, since using them may actually be more expensive (than not using them) for caching static pages.  Each benchmark was run 3 times, with the following parameters: concurrency level 5, number of requests 1000 (ab -c 5 -n 1000); the mean of those benchmarks was then derived.  Here are the environment specs:</p>
<pre class="prettyprint">
Linux Mint 4.0 (Ubuntu 7.10)
Apache 2.2.4
PHP 5.2.3
eAccelerator 0.9.5.2
</pre>
<h3>The results</h3>
<p>Static HTML file served by Apache resulted in 13528 RPS and 11397 RPS with eAccelerator enabled.  Finally, here are the benchmarks:<br />
<img src='http://pr0digy.com/wp/wp-content/uploads/2008/05/framework-performance.jpg' alt='Performance benchmark: Cake vs. CodeIgniter vs. Kohana' /></p>
<h3>Conclusion</h3>
<p>Cake has so many nice features, too bad it&#8217;s so incredibly slow - even with eAccelerator enabled, it&#8217;s about 30% slower than a plain CI/Kohana installation.  Unacceptable.  CodeIgniter and Kohana, on the other hand, show great results and come up just about even (330 RPS, 326 RPS respectively) without eAccelerator.  With eAccelerator turned on, CodeIgniter is clearly the winner.  My <em>wild guess</em> is that eAccelerator does not play so nice with __autoload function, which is widely used in Kohana.</p>
]]></content:encoded>
			<wfw:commentRss>http://pr0digy.com/codeigniter/benchmark-static-cake-codeigniter-kohana/feed/</wfw:commentRss>
		</item>
		<item>
		<title>CodeIgniter model productivity methods</title>
		<link>http://pr0digy.com/codeigniter/model-productivity-methods/</link>
		<comments>http://pr0digy.com/codeigniter/model-productivity-methods/#comments</comments>
		<pubDate>Mon, 25 Feb 2008 11:51:25 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
		
		<category><![CDATA[codeigniter]]></category>

		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://pr0digy.com/codeigniter/model-productivity-methods/</guid>
		<description><![CDATA[Time saving methods for CodeIgniter model.]]></description>
			<content:encoded><![CDATA[<p>Just wanted to share a couple of methods, which I use in my models all the time.  One is for saving and updating, while the other is for retrieving data, both of the methods rely on active record class.</p>
<h3>Input array filter</h3>
<p>When saving data from web forms, I normally validate and XSS filter all of the necessary elements of the $_POST array and then simply pass it to a model method.  The problem is that often, in the $_POST array, there are extra fields that do not exist in the target table (fields used for controller logic - navigation etc). Obviously, trying to insert a field that does not exist in a table will trigger an error.  One way around that is to manually unset all of the unnecessary elements in the $_POST array.  That solution, however, does not scale at all and the code looks ugly.  For that reason, I&#8217;ve written a method that will compare input array keys to the target table field names and unset all of the elements that do not match.  Additionally, the input array can be passed through the XSS filter; that functionality is turned off by default.  Here is the sample code:</p>
<p><strong>Model methods</strong></p>
<pre class="prettyprint">

/**
 * Make sure that the incoming array does not contain any
 * fields which are not in the target table.
 * Additionally, input can be XSS filtered.
 *
 * @access 	protected
 * @param 	string
 * @param 	array
 * @param   boolean
 * @return 	array
 *
 */
protected function filterInputArray($table, $data, $xss_clean = false){
	$fields = $this->db->list_fields($table);

	foreach ($data as $k => $v) {
		if(in_array($k, $fields) == false){
			unset($data[$k]);
		} else {
			if($xss_clean === true) $data[$k] = $this->input->xss_clean($v);
		}
	}

	return $data;
}

//a typical update method
public function updateMethod($id, $data = array()){
	$data = $this->filterInputArray('users', $data);
	$this->db->where('id', $id);
	$this->db->update('users', $data);
	return $this->db->affected_rows();
}

//a typical insert method
public function insertMethod($data = array()){
	$data = $this->filterInputArray('users', $data);
	$this->db->insert('users', $data);
	return $this->db->insert_id();
}
</pre>
<p><strong>How you would call it from a Controller</strong></p>
<pre class="prettyprint">
public function someMethod(){
	//load and configure validation
	$this->load->library('validation');

	//run validation
	if ($this->validation->run() == true){
		//load the model
		$this->load->model('User_model', 'users');

		//call the insert method
		$user_id = $this->users->insertMethod($_POST);

		//call the update method
		$this->users->updateMethod($user_id, $_POST);
	}
}
</pre>
<h3>Get result as an array</h3>
<p>This method is used for generating query results - it always returns an array, even if it&#8217;s an empty one.  It is built upon active record&#8217;s &#8216;get&#8217; method.  Essentially it eliminates the need to check if query has produced any result, as well as the need to call result_array() method.  Additionally, by default, the keys in the resulting array will be set to the value of &#8216;id&#8217; - this can be quite handy when working with arrays generated from dependent tables.  Take a look at the code:</p>
<p><strong>Model methods</strong></p>
<pre class="prettyprint">

/**
 * Similar to active record's get method.
 * Will always return an array, even if the query did not yield any results.
 * By default, the reulting array's keys are equal to 'id'. That feature may
 * be disabled by passing false as an optional parameter.
 *
 * @access 	protected
 * @param 	boolean
 * @return 	array
 *
 */
protected function getArray($use_id_as_key = true){
	$res = $this->db->get();

	$items = array();

	if ($res->num_rows() > 0) {
        foreach ($res->result_array() as $k => $v) {
			foreach ($v as $kk => $vv) {
				if($use_id_as_key === true) $items[$v['id']][$kk] = $vv;
				else $items[$k][$kk] = $vv;
			}
		}
	} 

	return $items;
} 

//a typical select method
//can't get much easier that this (except for ORM of course :))
public function selectMethod($id){
	$this->db->from('users')->where('id', $id);
	return $this->getArray();
}
</pre>
<p><strong>How you would call it from a Controller</strong></p>
<pre class="prettyprint">
public function someMethod($user_id){
	//load the model
	$this->load->model('User_model', 'users');

	//get user by id
	$user = $this->users->selectMethod($user_id);
}
</pre>
<h3>Afterword</h3>
<p>The above methods save me a lot of the time and headache, so I hope you find them useful. If you decide to use those in your code, the best place for them would be in a parent model.</p>
]]></content:encoded>
			<wfw:commentRss>http://pr0digy.com/codeigniter/model-productivity-methods/feed/</wfw:commentRss>
		</item>
		<item>
		<title>MySQL character set problems</title>
		<link>http://pr0digy.com/mysql/character-set-problem/</link>
		<comments>http://pr0digy.com/mysql/character-set-problem/#comments</comments>
		<pubDate>Sun, 27 Jan 2008 11:31:04 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
		
		<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false">http://pr0digy.com/mysql/character-set-problem/</guid>
		<description><![CDATA[This article shows how to solve MySQL character set problems.]]></description>
			<content:encoded><![CDATA[<p>Recently I’ve ran into a problem with using character set other than default – cp125 (Cyrillic) in my case.  The problem isn’t very well documented, so I’ve decided to recap all the troubles I’ve encountered, in hopes that it may help a person or two :)</p>
<h3>The problem</h3>
<p>All of the strings in non default character set would show up as a bunch of question marks (привет = ??????).  I should note that this happened on my local machine, production server with similar data functioned just fine.</p>
<h3>Attempts to fix the problem</h3>
<p>If you’re only interested in the solution, you may skip to the conclusion.</p>
<p>Step 1:<br />
Naturally, first thing I did was searching MySQL documentation.  The solution was to change default character set by adding the following line to MySQL configuration file:</p>
<pre class="prettyprint">
init-connect='SET NAMES cp1251'
</pre>
<p>The above line, basically, changes character set at the time of connection.</p>
<p>Unfortunately the above code did not work for me.<br />
Step 2:<br />
Since tweaking MySQL settings did not yield any positive results, I’ve decided to check apache language configuration.  I’ve added extra encoding options and changed language priorities – nothing.</p>
<p>Step 3:<br />
Did more searching and found that using SET NAMES command should definitely work from within the script.  Gave it a shot and it did, in fact, work.  Theoretically, that solves the problem.  On practice, however, is not very convenient, nor does it lead to portable code.</p>
<p>Step 4:<br />
I figured that the command SET NAMES worked just fine, but for some reason did not execute from the MySQL configuration file – my assumption was correct.<br />
The script was establishing connection under ‘root’ user, which has all of the privileges – ironically that is what caused the problem.  Apparently, any connection established from a user with SUPER privilege, will not trigger init-connect.<br />
Sure enough, creating a user with appropriate privileges solved the problem.</p>
<h3>Conclusion</h3>
<p>Just to recap – the following things should be done in order to solve the problem:</p>
<p>1. Add the following line to MySQL configuration file, somewhere in [mysqld] section.</p>
<pre class="prettyprint">
init-connect='SET NAMES cp1251'
</pre>
<p>2. Make sure that your script is connecting with a user that does not have SUPER privilege.</p>
]]></content:encoded>
			<wfw:commentRss>http://pr0digy.com/mysql/character-set-problem/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Mootools Text Snow</title>
		<link>http://pr0digy.com/mootools/text-snow/</link>
		<comments>http://pr0digy.com/mootools/text-snow/#comments</comments>
		<pubDate>Wed, 19 Dec 2007 20:26:50 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
		
		<category><![CDATA[mootools]]></category>

		<guid isPermaLink="false">http://pr0digy.com/mootools/text-snow/</guid>
		<description><![CDATA[An easy way to create snow on your page.  Mootools class and how to use it.]]></description>
			<content:encoded><![CDATA[<div id="snow">
	<img src="http://pr0digy.com/sandbox/mootools/snow/images/xmass.jpg" alt="Merry Xmas" />
</div>
<p>It’s been a while since my last post – my excuse is a complete lack of time, due to high workload.  Anyway, just in time for Xmas, I have managed to find some spare time to write a Mootools class that simulates a snowfall.<br />
The class is pretty simple, yet there are many options to play with.  Although the title suggests that the snow is comprised of text symbols, you can also use HTML and therefore images, for snowflakes.<br />
Anyway, if this is something that you may be interested in using for the holiday season, here is how you would do it:</p>
<pre class="prettyprint">
&lt;script type=&quot;text/javascript&quot; src=&quot;js/mootools.v1.11.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;js/mootools.tsnow.js&quot;&gt;&lt;/script&gt;

&lt;script type=&quot;text/javascript&quot;&gt;
//&lt;![CDATA[
var Site = {

	start: function(){
		//basic usage, assumes that div#snow dimensions have been explicitly specified
		//div#snow is the container for the snowfall, needs to be created by hand
		new TextSnow({ container:$('snow') });

		//extended usage, all options are used
		new TextSnow({
			container:$('snow'),//container where you want the snowfall
			inject:'top',//insert stage inside, top, before or after the container

			stage:{
				//any number of css rules
				styles:{
					background:'#ccc',
					width: 100,
					height: 100
				},
				padding: 1//horisontal stage padding
			},

			snow:{
				ammount: 30,//number of snowflakes
				speed:[1,2,3],//speed with wich individual snowflakes fall

				//any number of css rules
				styles: {
					'position': 'absolute'
				},

				symbol: ['*', '.', '&lt;img src=&quot;img-url&quot; /&gt;', '&amp;raquo;'],//an array of flake symbols, html can be used as well
				color:['#fff','#eee','#eed'],//flake color
				fontFamily:['Impact', 'Times New Roman', 'Georgia'],//different flake shape
				fontSize:[20,22],//font size in pixels
				direction:'left',//left,right,straight
				sinkSpeed:50//how fast the snow is falling (lower number = higher speed)
			}
		});
	}
};

window.addEvent('domready', Site.start);
//]]&gt;
&lt;/script&gt;

&lt;!-- CSS used for the example on my site --&gt;
&lt;style type=&quot;text/css&quot;&gt;
	#snow{height: 500px; width: 750px; position: relative;}
	#snow img{position: absolute; top:0; left: 0;}
&lt;/style&gt;
</pre>
<p>The script can be downloaded <a href="http://pr0digy.com/sandbox/mootools/snow/js/mootools.tsnow.js">here</a>.  Oh and Merry Christmas &amp; Happy New Year!</p>
]]></content:encoded>
			<wfw:commentRss>http://pr0digy.com/mootools/text-snow/feed/</wfw:commentRss>
		</item>
		<item>
		<title>CodeIgniter - loading external libraries</title>
		<link>http://pr0digy.com/codeigniter/loading-external-libraries/</link>
		<comments>http://pr0digy.com/codeigniter/loading-external-libraries/#comments</comments>
		<pubDate>Mon, 08 Oct 2007 16:17:25 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
		
		<category><![CDATA[codeigniter]]></category>

		<guid isPermaLink="false">http://pr0digy.com/codeigniter/loading-external-libraries/</guid>
		<description><![CDATA[A very simple way to load external libraries into CodeIgniter.]]></description>
			<content:encoded><![CDATA[<p>CodeIgniter provides a simple way to load libraries located in the application folder.  Personally, I prefer to store most of the libraries in a common centralized location.  Unfortunately, there is no elegant built in solution to access such external libraries.  One may suggest using hooks, but that seems like too much hassle to me.<br />
Fortunately, for those using PHP5, there is an easy way out.  PHP5 offers a few really neat functions that can make your life quite a bit easier, one of them is __autoload.  This function will try to load a class file if it’s not already loaded, simple.<br />
The best place to place __autoload function is the config.php file, as it is one of the first to be included by CodeIgniter system.  Here’s the config.php snippet:</p>
<pre class="prettyprint">
function __autoload($class) {
    //prevent CI and Pear classes from being loaded.
    if(!strstr($class, 'CI') &amp;&amp; !stristr($class, 'PEAR')){
        require_once(PATH_TO_LIBRARIES.&quot;$class.php&quot;);
    }
}
</pre>
<p>Essentially, by parsing the class name, you can create different loading routines for different libraries.  After you’ve set up the __autoload function, call your classes as usual (new, extends, implements and static method calls, should all trigger __autoload).</p>
]]></content:encoded>
			<wfw:commentRss>http://pr0digy.com/codeigniter/loading-external-libraries/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Mootools text drop-shadow</title>
		<link>http://pr0digy.com/mootools/text-dropshadows/</link>
		<comments>http://pr0digy.com/mootools/text-dropshadows/#comments</comments>
		<pubDate>Thu, 19 Jul 2007 11:13:17 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
		
		<category><![CDATA[mootools]]></category>

		<guid isPermaLink="false">http://pr0digy.com/mootools/text-dropshadows/</guid>
		<description><![CDATA[A convenient way of creating text drop-shadows, using MooTools.]]></description>
			<content:encoded><![CDATA[<p>Text drop shadows can be used to improve headline legibility or simply for decorative purpose.  In my latest project, I’ve had to use drop shadows just for the reasons above and ended up writing a Mootools class.<br />
There are a few techniques to generate text drop shadows, all of which are based on creating a duplicate text layer to simulate a drop shadow, but not all of them are scalable; meaning that when user resizes web page text, using browser controls (ctr +/-,ctr + mouse scroll, etc), the drop shadow may not always follow the element it’s supposed to shadow.  In the particular technique I’m using, however, a container div is used to hold both text elements, insuring a uniform look, regardless of the size.  Although, it may not scale as <em>nicely</em> as one would expect, in certain situations&#8230;</p>
<p>You can take a look at the demo <a href="http://www.pr0digy.com/sandbox/mootools/text-ds/">here</a>.  If that’s something you may be interested in, here is how to use it (also check out the demo&#8217;s source code for more examples):</p>
<pre class="prettyprint">
&lt;script type=&quot;text/javascript&quot; src=&quot;js/mootools.v1.11.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;js/mootools.tds.js&quot;&gt;&lt;/script&gt;

&lt;script type=&quot;text/javascript&quot;&gt;
//&lt;![CDATA[

	var Site = {

		start: function(){
			//simple ds with no options
			new TextDropShadow($('element'));

			//all elements with particular class name
			new TextDropShadow($$('element.classname'));

			//set ds color to #222 and it's opacity to 50%
			//when using apacity, you must specify background color or IE will output junk
			new TextDropShadow($('element'), {color:'#222', opacity: 0.5, background: '#fff'});

			//specify color and direction
			new TextDropShadow($('element'), {color:'#222', top:2, left:2});

			//shadow direction can take negative values as well
			new TextDropShadow($('element'), {color:'#222', top:-1, left:-1});
		}

	};

	window.addEvent('domready', Site.start);
//]]&gt;
&lt;/script&gt;
</pre>
<p>The script is available for <a href="http://www.pr0digy.com/sandbox/mootools/text-ds/js/mootools.tds.js">download here</a>&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://pr0digy.com/mootools/text-dropshadows/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Live search with CodeIgniter and Mootools</title>
		<link>http://pr0digy.com/codeigniter/live-search-with-codeigniter-and-mootools/</link>
		<comments>http://pr0digy.com/codeigniter/live-search-with-codeigniter-and-mootools/#comments</comments>
		<pubDate>Sun, 08 Jul 2007 13:33:06 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
		
		<category><![CDATA[ajax]]></category>

		<category><![CDATA[codeigniter]]></category>

		<category><![CDATA[mootools]]></category>

		<guid isPermaLink="false">http://pr0digy.com/codeigniter/live-search-with-codeigniter-and-mootools/</guid>
		<description><![CDATA[Create a Live Search application with CodeIgniter and Mootools.]]></description>
			<content:encoded><![CDATA[<p>This article demonstrates how to create a live search application (an AJAX based application that returns search results as you type) with CodeIgniter and Mootools JSON.  You can take a look at the <a href="http://pr0digy.com/sandbox/ajax/livesearch">final product here</a>.  The application is build using JavaScript in non obtrusive ways, so it will function in just about any browser, even if they don’t support JavaScript at all.<br />
The article consists of five parts: model, view, controller, CodeIgniter JSON library and Mootools front end scripting, each with extensively commented source code.</p>
<h3>Model</h3>
<p>The SQL here is based on WP Search Reloaded plug-in.  It is a fairly sophisticated way of searching through text, but requires FULLTEXT index.  To simplify the example, this query is designed for search with a single term.</p>
<pre class="prettyprint">
/*     

CREATE TABLE `posts` (
  `id` int(11) unsigned NOT NULL auto_increment,
  `title` varchar(255) NOT NULL,
  `body` text NOT NULL,
  `date` timestamp NOT NULL default CURRENT_TIMESTAMP,
  PRIMARY KEY  (`id`),
  UNIQUE KEY `id` (`id`),
  FULLTEXT KEY `title` (`title`,`body`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

*/

//search posts table for matching terms - the method will produce an associative array
public function search($term) {
	$term = $this-&gt;db-&gt;escape($term);

	$sql = &quot;SELECT posts.*,
			CASE WHEN posts.title REGEXP $term THEN 1 ELSE 0 END AS keyword_in_title,
			MATCH ( posts.title, posts.body ) AGAINST ($term) AS mysql_score
			FROM posts
			WHERE ( posts.title REGEXP $term OR posts.body REGEXP $term )
			ORDER BY keyword_in_title DESC, mysql_score DESC, posts.date DESC LIMIT 0, 10&quot;;

	$res = $this-&gt;db-&gt;query($sql);	

	$items = array();

	if ($res-&gt;num_rows() &gt; 0) {

		$count = 0;
		foreach ($res-&gt;result() as $item) {

			foreach ($item as $key =&gt; $value) {
				$items[$count][$key] = $value;
			}

			$count++;
		}
	} 

	return $items;
}
</pre>
<h3>View</h3>
<p>This part is straight forward - a form for submitting search requests and a for loop to display the results.</p>
<pre class="prettyprint">
&lt;!-- header --&gt;

&lt;div id=&quot;form-container-wrapper&quot;&gt;
	&lt;div id=&quot;form-container&quot;&gt;
		&lt;form method=&quot;post&quot; id=&quot;ls-form&quot; action=&quot;&lt;?php site_url('ajax'); ?&gt;&quot;&gt;
			&lt;p&gt;
				&lt;label for=&quot;searchterm&quot; class=&quot;heading&quot;&gt;Start typing in the bessage box. Try &lt;strong&gt;CodeIgniter&lt;/strong&gt;, for example.&lt;/label&gt;
			&lt;/p&gt;
			&lt;p&gt;
				&lt;input type=&quot;text&quot; name=&quot;searchterm&quot; id=&quot;searchterm&quot; value=&quot;&quot; /&gt;
				&lt;input type=&quot;submit&quot; name=&quot;Submit&quot; id=&quot;submit&quot; value=&quot;Submit&quot; /&gt;
			&lt;/p&gt;

		&lt;/form&gt;
	&lt;/div&gt;&lt;!-- form-container --&gt;
&lt;/div&gt;&lt;!-- form-container-wrapper --&gt;

&lt;div id=&quot;search-results-wrapper&quot;&gt;
	&lt;div id=&quot;search-results&quot;&gt;

	&lt;?php if($posts): ?&gt;
		&lt;h2&gt;Search results:&lt;/h2&gt;
		&lt;?php $count = 1; foreach($posts as $key =&gt; $post) : ?&gt;

		&lt;h3&gt;&lt;?php echo $count; ?&gt;. &lt;?php echo $post['title']; ?&gt;&lt;/h3&gt;
		&lt;p&gt;&lt;?php echo $post['body']; ?&gt;&lt;/p&gt;

		&lt;?php $count++; endforeach; ?&gt;
	&lt;?php else: ?&gt;	

		&lt;h2&gt;Search results:&lt;/h2&gt;
		&lt;p&gt;Your query did not match any posts.&lt;/p&gt;

	&lt;?php endif; ?&gt;	

	&lt;/div&gt;&lt;!-- end search-results --&gt;
&lt;/div&gt;&lt;!-- end search-results-wrapper --&gt;

&lt;!-- footer--&gt;
</pre>
<h3>Controller</h3>
<p>Controller contains one key method that will render the related view upon a standard post request or dump a JSON encoded string upon an AJAX request.  You will need the JSON library for CodeIgniter to encode/decode that notation - the lib is provided further down the page.</p>
<pre class="prettyprint">
public function index(){
	$this-&gt;search('standard');
}

public function json(){
	$this-&gt;search('json');
}

public function search($transport = null){
	//load database
	$this-&gt;load-&gt;database();
	//load posts model
	$this-&gt;load-&gt;model('Posts', 'posts');
	//load JSON lib
	$this-&gt;load-&gt;library('JSON', 'json');

	//init posts array
	$posts = array();

	//validate and filter the input
	if(isset($_POST['searchterm']) &amp;&amp; !empty($_POST['searchterm'])){
		//clean the string, just in case
		$searchterm = strip_tags($_POST['searchterm']);
		//get the results if any
		$posts = $this-&gt;posts-&gt;search($searchterm);
	}

	//if request came from a JSON application
	if($transport == 'json'){
		//output the encoded string
		echo $this-&gt;json-&gt;encode($posts);
		//and exit, no reason to continue
		exit;
	}

	//assign post array
	$this-&gt;data['posts'] = $posts;
	//display the view
	$this-&gt;render('livesearch');
}
</pre>
<h3>JSON Library for CodeIgniter</h3>
<p>This is a wrapper for Services_JSON class from JSON&#8217;s <a href="http://json.org">official website</a>.  The library has two methods encode and decode, simple.  You can <a href="http://codeigniter.com/wiki/File:JSON_Library.zip/">download this library</a> from CodeIgniter’s WIKI.  To use the library, simply drop the contents of the zip file into the library folder in the application folder (not the library folder located in system).<br />
If you have PHP 5.2.0 or older, the above library will not be needed.  As of PHP 5.2.0, the JSON extension is bundled and compiled into PHP by default.</p>
<h3>JavaScript</h3>
<p>Finally after the application is completely functional, we can look into the fun part - Mootools :)  The JS part of the application sends an AJAX post request containing the search term(s) and in return receives an encoded JSON string.  The string is then decoded using Mootools JSON parser.  The resulting JS object is then used to build and display the search results.</p>
<pre class="prettyprint">
&lt;script type=&quot;text/javascript&quot;&gt;
//&lt;![CDATA[
	var Site = {

		start: function(){
			Site.liveSearch();
		},

		liveSearch: function(){
			//set focus on the search form
			$('searchterm').focus();

			//attach a keyup event to the searchfield
			$('searchterm').addEvent('keyup', function(event){

				//controller's URI
				var url = '&lt;?php echo site_url('livesearch/json'); ?&gt;';

				//AJAX request
				new Ajax(url, {

					method: 'post',
					onComplete: function(request){
						//prepare search container for new results
						$('search-results').empty();

						//if controller returned some results decode them
						if(request) var results = Json.evaluate(request);
						//pass results object to the output method
						if(results) Site.buildSearchResults(results);
					},
					//post search form
					postBody: $('ls-form')				

				}).request();

				//return false;
			});
		},

		buildSearchResults: function(results){
			//prepare the container for newly fetched results
			var container = $('search-results');
			var heading = new Element('h2').setHTML('Search results:').injectInside(container);

			//output the results
			results.each(function(result, i) {
				var title = new Element('h3').injectInside(container);
				var link = new Element('a', {'href': '#post-'+result.id}).setHTML((i+1)+'. '+result.title).injectInside(title);
				var body = new Element('p').setHTML(result.body).injectAfter(title);
				var br = new Element('br').injectAfter(body);
			});
		}

	};
	window.addEvent('domready', Site.start);
//]]&gt;
&lt;/script&gt;
</pre>
<h3>Further reading</h3>
<div class="post-metadata">
<a href="http://pr0digy.com/codeigniter/unobtrusive-ajax-with-codeigniter-and-mootools/">Unobtrusive AJAX with CodeIgniter and Mootools</a><br />
<a href="http://demos.mootools.net/Json.Remote">Mootools Json Remote demo</a><br />
<a href="http://docs.mootools.net/Remote/Json.js">Mootools Json docs</a>
</div>
]]></content:encoded>
			<wfw:commentRss>http://pr0digy.com/codeigniter/live-search-with-codeigniter-and-mootools/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Mootools Slide Effect: expand all, collapse all or use as accordion</title>
		<link>http://pr0digy.com/mootools/mootools-slide-effect/</link>
		<comments>http://pr0digy.com/mootools/mootools-slide-effect/#comments</comments>
		<pubDate>Sun, 24 Jun 2007 11:11:34 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
		
		<category><![CDATA[mootools]]></category>

		<guid isPermaLink="false">http://pr0digy.com/mootools/mootools-slide-effect-expand-all-collapse-all-use-as-an-accordion/</guid>
		<description><![CDATA[A detailed explanation of Mootools Slide Effect.  This article comes with a demonstration page.]]></description>
			<content:encoded><![CDATA[<p>I was using Mootools Fx.Slide to create a list based FAQ section, and ran into a bit of a problem while making all of the list items collapse or expand.  The solution is quite simple, but not immediately obvious.  In this article I’ll demonstrate how to expand and collapse all of the items in a list, and also a way to simulate an accordion.  Before we go any further, check out a <a href="http://pr0digy.com/sandbox/mootools/slide-effect/">demo page</a> for this article.</p>
<p>Applying slide effect to a single element is straight forward and looks something like this:</p>
<pre class="prettyprint">
var collapsible = new Fx.Slide($('target-element'), {
	duration: 500,
	transition: Fx.Transitions.linear
});

collapsible.toggle();
</pre>
<p>What’s not immediately obvious is that, the code above takes the target element and wraps it into a div with overflow set to hidden.  Whenever Fx.Slide is toggled, negative margin is applied to the target element and it, sort of, slides under the wrapping div.  Take a look at the HTML before and after the effect was applied:</p>
<pre class="prettyprint">
&lt;!-- before the effect is applied --&gt;
&lt;li&gt;
	&lt;div  class=&quot;collapse&quot;&gt;
		&lt;p&gt;Some text here&lt;/p&gt;
	&lt;/div&gt;
&lt;/li&gt;

&lt;!-- after slideIn effect was applied --&gt;
&lt;li&gt;
	&lt;div style=&quot;overflow: hidden; height: 0px;&quot;&gt;
		&lt;div class=&quot;collapse&quot; style=&quot;margin: -100px 0 0;&quot;&gt;
			&lt;p&gt;Some text here&lt;/p&gt;
		&lt;/div&gt;
	&lt;/div&gt;
&lt;/li&gt;

&lt;!-- after slideOut effect was applied --&gt;
&lt;li&gt;
	&lt;div style=&quot;overflow: hidden; height: 100px;&quot;&gt;
		&lt;div class=&quot;collapse&quot; style=&quot;margin: 0;&quot;&gt;
			&lt;p&gt;Some text here&lt;/p&gt;
		&lt;/div&gt;
	&lt;/div&gt;
&lt;/li&gt;
</pre>
<p>Once you understand how Fx.Slide functions, it becomes clear that this effect cannot be applied to any particular target more than once.  With that in mind, the solution for collapsing or expanding all items is quite simple – store all of the Fx.Slide references in an array, then upon a request loop through the array and for each element in it, apply the desired effect.  Here is the code:</p>
<pre class="prettyprint">
//list of target elements
var list = $$('#collapse li div.collapse');
//list elements to be clicked on
var headings = $$('#collapse li h3');
//array to store all of the collapsibles
var collapsibles = new Array();

headings.each( function(heading, i) {

	//for each element create a slide effect
	var collapsible = new Fx.Slide(list[i], {
		duration: 500,
		transition: Fx.Transitions.linear
	});

	//and store it in the array
	collapsibles[i] = collapsible;

	//add event listener
	heading.onclick = function(){
		collapsible.toggle();
		return false;
	}

	//collapse all of the list items
	collapsible.hide();

});

//collapse all
$('collapse-all').onclick = function(){
	headings.each( function(heading, i) {
		collapsibles[i].hide();
	});
}

//expand all
$('expand-all').onclick = function(){
	headings.each( function(heading, i) {
		collapsibles[i].show();
	});
}
</pre>
<p>Also, by adding just a few more lines of code we can simulate an accordion:</p>
<pre class="prettyprint">
headings.each( function(heading, i) {

	//for each element create a slide effect
	var collapsible = new Fx.Slide(list[i], {
		duration: 500,
		transition: Fx.Transitions.linear
	});

	//and store it in the array
	collapsibles[i] = collapsible;

	//add event listener
	heading.onclick = function(){

		//open current element
		collapsible.toggle();

		//hide the rest
		for(var j = 0; j < collapsibles.length; j++){
			if(j!=i) collapsibles[j].slideOut();
		}

		return false;
	}

	//collapse all of the list items
	collapsible.hide();

});
</pre>
<p>Take a look at the source code of the <a href="http://pr0digy.com/sandbox/mootools/slide-effect/">demo page</a> to see more elaborate code examples.</p>
]]></content:encoded>
			<wfw:commentRss>http://pr0digy.com/mootools/mootools-slide-effect/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Nikon D40x – my new camera</title>
		<link>http://pr0digy.com/digital-imaging/nikon-d40x/</link>
		<comments>http://pr0digy.com/digital-imaging/nikon-d40x/#comments</comments>
		<pubDate>Sat, 16 Jun 2007 17:11:40 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
		
		<category><![CDATA[digital imaging]]></category>

		<guid isPermaLink="false">http://pr0digy.com/digital-imaging/nikon-d40x/</guid>
		<description><![CDATA[A short review of Nikon D40x, and a couple of sample images.]]></description>
			<content:encoded><![CDATA[<p>Just as the title suggests, I’ve recently purchased a <a href="http://www.dpreview.com/reviews/nikond40x/">Nikon D40x</a> camera kit.  I haven&#8217;t had much time to play around with it yet, but managed to take a few nice macro shots, while taking a stroll in the garden.  Here are a couple of samples:</p>
<p><strong>A massive honey bee, harvesting a blooming green onion</strong></p>
<pic here>
<img src='http://pr0digy.com/wp/wp-content/uploads/2007/06/d40x-01-22.jpg' alt='Some kind of massive honey bee, farming a green onion' /></p>
<p>See the <a href='http://pr0digy.com/wp/wp-content/uploads/2007/06/honey-bee-on-green-onion.jpg' title='Some kind of massive honey bee, farming a green onion'>original</a> (~3.5Mb).</p>
<p><strong>Neat tiny flowers, which I suspect may be giving me allergies :)</strong></p>
<pic here>
<img src='http://pr0digy.com/wp/wp-content/uploads/2007/06/d40x-05-22.jpg' alt='Neat tiny flowers' /></p>
<p>See the <a href='http://pr0digy.com/wp/wp-content/uploads/2007/06/tiny-yellow-green-flowers.jpg' title='Neat tiny flowers'>original</a> (~3.7Mb).</p>
<p>Thus far I’m very impressed with the controls, as well as camera&#8217;s excellent performance.  The autofocus, however, is a bit disappointing – it seems incapable of focusing on some things that my old camera had absolutely no problems with.  I suspect it has something to do with the particular lens that is being used at the moment.  To make any conclusions about it, I’d have to play around with the camera a bit more, see how it behaves with other lenses.</p>
<p>There are some more macro shots from this <a href="http://kartinka.ws/album/d40xm">set</a>, available at <a href="http://kartinka.ws/">Kartinka</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://pr0digy.com/digital-imaging/nikon-d40x/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
