<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>modules/hook_test/config/hooks.php</filename>
    </added>
    <added>
      <filename>modules/hook_test/controllers/hook_test.php</filename>
    </added>
    <added>
      <filename>modules/hook_test/functions/hook_test.php</filename>
    </added>
    <added>
      <filename>modules/hook_test/libraries/my_second_hook.php</filename>
    </added>
    <added>
      <filename>modules/twitter/controllers/twitter.php</filename>
    </added>
    <added>
      <filename>modules/twitter/views/twitter/tweets.php</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -727,8 +727,8 @@ function gzip_compression() {
  * Return a singleton instance of the current controller
  * @return object
  */
-function &amp;get_instance(){
-	return core::get_instance();
+function get_instance(){
+	return controller::get_instance();
 }
 
 </diff>
      <filename>functions/common.php</filename>
    </modified>
    <modified>
      <diff>@@ -10,7 +10,7 @@
  * @copyright	Copyright (c) 2009 MicroMVC
  * @license		http://www.gnu.org/licenses/gpl-3.0.html
  * @link		http://micromvc.com
- * @version		1.0.1 &lt;5/31/2009&gt;
+ * @version		1.1.0 &lt;7/7/2009&gt;
  ********************************** 80 Columns *********************************
  */
 </diff>
      <filename>index.php</filename>
    </modified>
    <modified>
      <diff>@@ -2,16 +2,18 @@
 /**
  * File Uploading Class
  *
+ * Allows easy uploading of files.
+ *
  * @package		MicroMVC
  * @author		David Pennington
  * @copyright	Copyright (c) 2009 MicroMVC
  * @license		http://www.gnu.org/licenses/gpl-3.0.html
  * @link		http://micromvc.com
- * @version		1.0.1 &lt;5/31/2009&gt;
+ * @version		1.1.0 &lt;7/7/2009&gt;
  ********************************** 80 Columns *********************************
  */
 class upload {
-	
+
 	//An array of error messages
 	public $error_messages	= array();
 	//The array to hold upload errors (if any)
@@ -41,17 +43,17 @@ class upload {
 	//Should the file name be changed to a random hash value?
 	public $encrypt_name	= FALSE;
 
-	
+
 	/*
 	 * On object creation set the error messages
 	 */
 	public function __construct() {
-		
+
 		//Make the allowed types an array (if not already)
 		if($this-&gt;allowed_types &amp;&amp; !is_array($this-&gt;allowed_types)) {
 			$this-&gt;allowed_types = explode('|', $this-&gt;allowed_types);
 		}
-		
+
 		$errors = array();
 		$errors['upload_no_file_selected'] = &quot;You did not select a file to upload.&quot;;
 		$errors['upload_bad_destination'] = 'The destination directory does not exist or is not writable.';
@@ -64,12 +66,12 @@ class upload {
 		$errors['upload_invalid_filetype'] = &quot;The filetype you are attempting to upload is not allowed.&quot;;
 		$errors['upload_invalid_filesize'] = &quot;The file you are attempting to upload is larger than the permitted size.&quot;;
 		$errors['upload_destination_error'] = &quot;A problem was encountered while attempting to move the uploaded file to the final destination.&quot;;
-		
+
 		$this-&gt;error_messages = $errors;
-		
+
 	}
-	
-	
+
+
 	/**
 	 * Perform the file upload
 	 *
@@ -77,7 +79,7 @@ class upload {
 	 * @return	bool
 	 */
 	function do_upload($field = 'userfile') {
-		
+
 		// Is $_FILES[$field] set? If not, no reason to continue.
 		if ( ! isset($_FILES[$field])) {
 			$this-&gt;set_error('upload_no_file_selected');
@@ -92,7 +94,7 @@ class upload {
 
 		// Was the file able to be uploaded? If not, determine the reason why.
 		if ( ! is_uploaded_file($_FILES[$field]['tmp_name'])) {
-			
+
 			$error = ( ! isset($_FILES[$field]['error'])) ? 4 : $_FILES[$field]['error'];
 
 			switch($error) {
@@ -123,23 +125,23 @@ class upload {
 
 			return FALSE;
 		}
-		
+
 		//Clean the file name and also get the extension
 		$this-&gt;process_filename($_FILES[$field]['name']);
-		
+
 		//Set the full file path
 		$file_path = $this-&gt;upload_path. $this-&gt;file_name. $this-&gt;file_ext;
-		
+
 		// Set the uploaded data as class variables
 		$this-&gt;file_temp = $_FILES[$field]['tmp_name'];
 		$this-&gt;file_size = $_FILES[$field]['size'];
 		$this-&gt;file_type = preg_replace(&quot;/^(.+?);.*$/&quot;, &quot;\\1&quot;, $_FILES[$field]['type']);
-	
+
 		// Convert the file size to kilobytes
 		if ($this-&gt;file_size &gt; 0) {
 			$this-&gt;file_size = round($this-&gt;file_size/1024, 2);
 		}
-		
+
 		// Is the file type allowed to be uploaded?
 		if ($this-&gt;allowed_types &amp;&amp; ( ! in_array($this-&gt;file_ext, $this-&gt;allowed_types))) {
 			$this-&gt;set_error('upload_invalid_filetype');
@@ -152,7 +154,7 @@ class upload {
 			return FALSE;
 		}
 
-		
+
 		/*
 		 * Move the file to the final destination
 		 * To deal with different server configurations
@@ -174,7 +176,7 @@ class upload {
 	/**
 	 * Set the file name
 	 *
-	 * This function takes a filename as input and filters it to make it safe 
+	 * This function takes a filename as input and filters it to make it safe
 	 * for use. It also gets the file extension. Finally, it looks for the
 	 * existence of a file with the same name. If found, it will append a
 	 * number to the end of the filename to avoid overwriting a pre-existing file.
@@ -185,33 +187,33 @@ class upload {
 	 * @return	string
 	 */
 	function process_filename($filename='') {
-		
+
 		//First get the extension of the file
 		$ext = strrchr($filename, '.');
-		
+
 		//Then get the file name
 		$filename = ($ext === FALSE) ? $filename : substr($filename, 0, -strlen($ext));
-		
+
 		//Should we encrypt the filename?
 		if ($this-&gt;encrypt_name == TRUE) {
 			mt_srand();
 			//Set the file name to a random value
 			$filename = md5(uniqid(mt_rand()));
-			
+
 		} else {
-		
+
 			//Make the files name &quot;filename&quot; safe (no weird chars allowed like &quot;/&quot;)
 			$filename = sanitize_text($filename, 4);
-			
+
 			/*
-			 * Separate extensions with &quot;_&quot; to prevent possible script execution 
+			 * Separate extensions with &quot;_&quot; to prevent possible script execution
 			 * from Apache's handling of files with multiple extensions.
 			 * http://httpd.apache.org/docs/1.3/mod/mod_mime.html#multipleext
 			 */
 			if(strpos($filename, '.')) {
 				//First, break apart the name into pieces
 				$parts = explode('.', $filename);
-				
+
 				foreach($parts as &amp;$part) {
 					//If this extension is not allowed
 					if(!in_array($part, $this-&gt;allowed_types)) {
@@ -219,20 +221,20 @@ class upload {
 						$part .= '_';
 					}
 				}
-				
+
 				//Put the filename back togeither
 				$filename = implode('.', $parts);
 			}
-			
+
 		}
-		
-		
+
+
 		//Check to see if the file with this name exists already
 		if (file_exists($this-&gt;upload_dir. $filename. $ext)) {
-			
+
 			//If we should NOT overwrite the existing files
 			if( ! $this-&gt;overwrite) {
-				//Then keep adding a number to the file name 
+				//Then keep adding a number to the file name
 				//until you find one that doesn't exist!
 				for ($i = 1; $i &lt; 1000; $i++) {
 					if ( ! file_exists($this-&gt;upload_dir. $filename. $i. $ext)) {
@@ -242,11 +244,11 @@ class upload {
 				}
 			}
 		}
-		
+
 		//Set the name and file extension
 		$this-&gt;file_name = $filename;
 		$this-&gt;file_ext = $ext;
-		
+
 	}
 
 </diff>
      <filename>libraries/Upload.php</filename>
    </modified>
    <modified>
      <diff>@@ -5,9 +5,9 @@
  * ABSTRACT
  *
  * After looking over the current PHP Akismet API classes (http://askimet.com)
- * I couldn't help but notice they all used fopen() to talk with akismet. 
- * Which besides being slow is also disabled on some hosts that have 
- * &quot;safe mode&quot; on. This class solves that problem by using the fast CURL 
+ * I couldn't help but notice they all used fopen() to talk with akismet.
+ * Which besides being slow is also disabled on some hosts that have
+ * &quot;safe mode&quot; on. This class solves that problem by using the fast CURL
  * php extension (http://php.net/curl) available on most web hosts.
  *
  * EXAMPLE
@@ -23,17 +23,17 @@
  *     'comment_content'           =&gt; 'This is a test comment',
  *     'permalink'                 =&gt; 'http://yoursite.com/post.php?id=9999',
  * );
- * 
+ *
  * $akismet = new akismet('akismet_api_key');
- * 
+ *
  * //If there was no problem connecting to Akismet.
  * if(!$akismet-&gt;error) {
- *     
+ *
  *     //Check to see if the key is valid
  *     if($akismet-&gt;valid_key()) {
  *         print 'Akismet Key is valid!';
  *     }
- *     
+ *
  *     if($akismet-&gt;is_spam($bad_comment)) {
  *         print 'Comment Spam!';
  *     } else {
@@ -48,7 +48,7 @@
  * @copyright	Copyright (c) 2009 MicroMVC
  * @license		http://www.gnu.org/licenses/gpl-3.0.html
  * @link		http://micromvc.com
- * @version		1.0.1 &lt;5/31/2009&gt;
+ * @version		1.1.0 &lt;7/7/2009&gt;
  ********************************** 80 Columns *********************************
  */
 
@@ -57,15 +57,15 @@
 
 // Used by the Akismet class to communicate with the Akismet service
 class akismet {
-    
+
     private $connection_handle;
     private $urls = array();
     public $api_version = '1.1';
     public $api_key;
     public $site_url;
     public $error = null;
-    
-    
+
+
     /**
      * Class Constructor function
      *
@@ -75,11 +75,11 @@ class akismet {
      * @return	void
     */
     function __construct($api_key=null, $site_url=null) {
-        
+
     	$this-&gt;setup($api_key, $site_url);
     }
-    
-    
+
+
     /**
      * Class Setup function
      *
@@ -96,7 +96,7 @@ class akismet {
             trigger_error('Akismet API Key not set.');
             $this-&gt;error = true;
         }
-        
+
         //If no site URL was given
         if(!$site_url) {
             //Set it to the current site
@@ -105,7 +105,7 @@ class akismet {
             //Set the site url
             $this-&gt;site_url = $site_url;
         }
-        
+
         //Set the REST API URL's that we will use
         $this-&gt;urls = array(
                     'verify' =&gt; 'rest.akismet.com/'. $this-&gt;api_version
@@ -117,13 +117,13 @@ class akismet {
                     'submit_ham' =&gt; $this-&gt;api_key. '.rest.akismet.com/'
                                  . $this-&gt;api_version. '/submit-ham'
                     );
-        
+
         //Now connect
         $this-&gt;connect();
-        
+
     }
-    
-    
+
+
     /**
      * Initializes a new cURL session/handle
      *
@@ -131,7 +131,7 @@ class akismet {
      * @return	boolean
     */
     public function connect() {
-       
+
         //If there is no connection
         if(!is_resource($this-&gt;connection_handle)) {
             //Try to create one
@@ -141,26 +141,26 @@ class akismet {
                 return;
             }
         }
-        
+
         //Include header in result? (no)
         curl_setopt($this-&gt;connection_handle, CURLOPT_HEADER, 0);
         //Do a regular HTTP POST? (yes)
         curl_setopt($this-&gt;connection_handle, CURLOPT_POST, 1);
         //The maximum number of seconds to allow cURL to execute
-        curl_setopt($this-&gt;connection_handle, CURLOPT_TIMEOUT, 6); 
+        curl_setopt($this-&gt;connection_handle, CURLOPT_TIMEOUT, 6);
         //Return the transfer as a string - instead of printing it
         curl_setopt($this-&gt;connection_handle, CURLOPT_RETURNTRANSFER, 1);
         //The &quot;User-Agent&quot; header to be used in a HTTP request
-        curl_setopt($this-&gt;connection_handle, CURLOPT_USERAGENT, 
+        curl_setopt($this-&gt;connection_handle, CURLOPT_USERAGENT,
                     &quot;MicroMVC/1.0.0 | Askimet/1.0.0&quot;);
         //Don't use a cached version of the url
         curl_setopt($this-&gt;connection_handle, CURLOPT_FRESH_CONNECT, 1);
-        
+
         return true;
-        
+
     }
-    
-    
+
+
     /**
      * Close the current cURL session/handle
      *
@@ -168,7 +168,7 @@ class akismet {
      * @return	boolean
     */
     public function close() {
-    
+
         //If there is no connection
         if(is_resource($this-&gt;connection_handle)) {
             //Try to close it
@@ -179,10 +179,10 @@ class akismet {
             }
         }
         return true;
-        
+
     }
-    
-    
+
+
     /**
      * Send a request through the current cURL session
      *
@@ -192,26 +192,26 @@ class akismet {
      * @return	boolean|string
     */
     private function send_data($request=null, $url=null) {
-    
+
         //Set the url to send data too
         curl_setopt($this-&gt;connection_handle, CURLOPT_URL, $url);
         //The data to post in the HTTP operation
         curl_setopt($this-&gt;connection_handle, CURLOPT_POSTFIELDS, $request);
-        
+
         //Send Data and grab the result
         $response = curl_exec($this-&gt;connection_handle);
-        
+
         //If the request failed
         if(!$response) {
             trigger_error('Could not send cURL request');
             $this-&gt;error = true;
             return;
         }
-        
+
         return $response;
     }
-    
-    
+
+
     /**
      * Check if Akismet API key is valid
      *
@@ -224,8 +224,8 @@ class akismet {
         );
         return ($this-&gt;send_data($string, $this-&gt;urls['verify']) == 'valid');
     }
-    
-    
+
+
     /**
      * Format the comment array in accordance to the Akismet API
      *
@@ -236,19 +236,19 @@ class akismet {
     public function is_spam($comment) {
         //Add this site_url
         $comment['blog'] = $this-&gt;site_url;
-        
+
         //Convert array to string
         $comment = $this-&gt;create_query_string($comment);
         //Add $_SERVER data to string
         $comment .= $this-&gt;create_server_string();
-        
+
         //Send the request to Akismet!
         $response = $this-&gt;send_data($comment, $this-&gt;urls['check_spam']);
         return ($response == 'true');
-        
+
     }
-    
-    
+
+
     /**
      * Submit a comment that Akismet missed as SPAM!
      *
@@ -258,26 +258,26 @@ class akismet {
      * @return	void
     */
     public function submit_spam($comment, $server_data=null) {
-        
+
         //Add this site_url
         $comment['blog'] = $this-&gt;site_url;
-        
+
         //Convert array to string
         $comment = $this-&gt;create_query_string($comment);
-        
+
         //Optionally add stored $_SERVER data about the spam
         if($server_data) {
             //Add stored $_SERVER data to the string.
             //Note: do NOT use current user's data as it might be an admin!
             $comment .= $this-&gt;create_query_string($server_data);
         }
-        
+
         //Send the request to Akismet!
         $this-&gt;send_data($comment, $this-&gt;urls['submit_spam']);
-        
+
     }
-    
-    
+
+
     /**
      * Let Akismet know that the comment was valid and NOT spam.
      *
@@ -287,26 +287,26 @@ class akismet {
      * @return	void
     */
     public function submit_ham($comment, $server_data=null) {
-        
+
         //Add this site_url
         $comment['blog'] = $this-&gt;site_url;
-        
+
         //Convert array to string
         $comment = $this-&gt;create_query_string($comment);
-        
+
         //Optionally add stored $_SERVER data about the spam
         if($server_data) {
             //Add stored $_SERVER data to the string.
             //Note: do NOT use current user's data as it might be an admin!
             $comment .= $this-&gt;create_query_string($server_data);
         }
-        
+
         //Send the request to Akismet!
         $this-&gt;send_data($comment, $this-&gt;urls['submit_ham']);
-        
+
     }
-    
-    
+
+
     /**
      * Build a query string containing the items in the given array
      *
@@ -322,8 +322,8 @@ class akismet {
         }
         return $query_string;
     }
-    
-    
+
+
     /**
      * Build a query string containing $_SERVER info to help Akismet fight spam!
      *
@@ -331,22 +331,22 @@ class akismet {
      * @return	String
      */
     private function create_server_string() {
-        
+
         $array = array(
             'SERVER_PROTOCOL' =&gt; $_SERVER['SERVER_PROTOCOL'],
             'REQUEST_METHOD' =&gt; $_SERVER['REQUEST_METHOD'],
-            'QUERY_STRING' =&gt; (isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : null), 
-            'HTTP_REFERER' =&gt; $_SERVER['HTTP_REFERER'], 
-            'REMOTE_PORT' =&gt; $_SERVER['REMOTE_PORT'], 
+            'QUERY_STRING' =&gt; (isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : null),
+            'HTTP_REFERER' =&gt; $_SERVER['HTTP_REFERER'],
+            'REMOTE_PORT' =&gt; $_SERVER['REMOTE_PORT'],
             'HTTP_ACCEPT' =&gt; $_SERVER['HTTP_ACCEPT'],
-            'user_agent' =&gt; $_SERVER['HTTP_USER_AGENT'], 
-            'referrer' =&gt; $_SERVER['HTTP_REFERER'], 
-            'user_ip' =&gt; ($_SERVER['REMOTE_ADDR'] != getenv('SERVER_ADDR')) ? 
+            'user_agent' =&gt; $_SERVER['HTTP_USER_AGENT'],
+            'referrer' =&gt; $_SERVER['HTTP_REFERER'],
+            'user_ip' =&gt; ($_SERVER['REMOTE_ADDR'] != getenv('SERVER_ADDR')) ?
                         $_SERVER['REMOTE_ADDR'] : getenv('HTTP_X_FORWARDED_FOR'),
             'blog' =&gt; $this-&gt;site_url);
-        
+
         return $this-&gt;create_query_string($array);
     }
-    
+
 }
 </diff>
      <filename>libraries/akismet.php</filename>
    </modified>
    <modified>
      <diff>@@ -10,7 +10,7 @@
  * @copyright	Copyright (c) 2009 MicroMVC
  * @license		http://www.gnu.org/licenses/gpl-3.0.html
  * @link		http://micromvc.com
- * @version		1.0.1 &lt;5/31/2009&gt;
+ * @version		1.1.0 &lt;7/7/2009&gt;
  ********************************** 80 Columns *********************************
  */
 </diff>
      <filename>libraries/base.php</filename>
    </modified>
    <modified>
      <diff>@@ -9,7 +9,7 @@
  * @copyright	Copyright (c) 2009 MicroMVC
  * @license		http://www.gnu.org/licenses/gpl-3.0.html
  * @link		http://micromvc.com
- * @version		1.0.1 &lt;5/31/2009&gt;
+ * @version		1.1.0 &lt;7/7/2009&gt;
  ********************************** 80 Columns *********************************
  */
 class cache {</diff>
      <filename>libraries/cache.php</filename>
    </modified>
    <modified>
      <diff>@@ -7,11 +7,10 @@
  * @package		MicroMVC
  * @author		Ioannis Cherouvim
  * @author		David Pennington
- * @copyright	Copyright (c) 2008 CodeXplorer
+ * @copyright	Copyright (c) 2009 MicroMVC
  * @license		http://www.gnu.org/licenses/gpl-3.0.html
- * @link		http://hack.gr
- * @link		http://codexplorer.com
- * @version		1.0.0 &lt;9/23/2008&gt;
+ * @link		http://micromvc.com
+ * @version		1.1.0 &lt;7/7/2009&gt;
  ********************************** 80 Columns *********************************
  */
 
@@ -47,26 +46,26 @@ class captcha {
 	 */
 
 	public function create($text=null, $file=null, $size=null) {
-	  
+
 		//Default to {site_root}/captcha.png
 		$file = SITE_DIR. ($file ? $file : 'captcha'). '.png';
-	  
-	  
+
+
 		//IF no text for the captcha image was set
 		if(!$text) {
 			//trigger_error('No text for the CAPTCHA was given', E_USER_NOTICE);
 			//return;
 			$text = random_charaters(6);
 		}
-	  
+
 		//IF no size is set = defualt to &quot;3&quot;
 		if(!$size) {$size=3;}
 
 		$font = 4;
 		$cosrate = rand(10,19);
 		$sinrate = rand(10,18);
-	  
-	  
+
+
 		$charwidth = @imagefontwidth($font);
 		$charheight = @imagefontheight($font);
 		$width=(strlen($text)+2)*$charwidth;
@@ -75,52 +74,52 @@ class captcha {
 		$im = @imagecreatetruecolor($width, $height)
 		or trigger_error('Cannot Initialize new GD image stream! (Is GD installed?)');
 		$im2 = imagecreatetruecolor($width*$size, $height*$size);
-	  
+
 		//Here we make the background and text alternate between light and dark
 		$bcol = imagecolorallocate($im, rand(80,100), rand(80,100), rand(80,100));
 		$fcol = imagecolorallocate($im, rand(150,200), rand(150,200), rand(150,200));
-	  
-	  
+
+
 		imagefill($im, 0, 0, $bcol);
 		imagefill($im2, 0, 0, $bcol);
-	  
+
 		$dotcol = imagecolorallocate($im, (abs($this-&gt;rbg_red($fcol)-$this-&gt;rbg_red($bcol)))/4,
 		(abs($this-&gt;rbg_green($fcol)-$this-&gt;rbg_green($bcol)))/4,
 		(abs($this-&gt;rbg_blue($fcol)-$this-&gt;rbg_blue($bcol)))/4);
-	  
+
 		$dotcol2 = imagecolorallocate($im, (abs($this-&gt;rbg_red($fcol)-$this-&gt;rbg_red($bcol)))/2,
 		(abs($this-&gt;rbg_green($fcol)-$this-&gt;rbg_green($bcol)))/2,
 		(abs($this-&gt;rbg_blue($fcol)-$this-&gt;rbg_blue($bcol)))/2);
-	  
+
 		$linecol = imagecolorallocate($im, (abs($this-&gt;rbg_red($fcol)-$this-&gt;rbg_red($bcol)))/2,
 		(abs($this-&gt;rbg_green($fcol)-$this-&gt;rbg_green($bcol)))/2,
 		(abs($this-&gt;rbg_blue($fcol)-$this-&gt;rbg_blue($bcol)))/2);
-	  
-	  
+
+
 		//Groups and warps Pixels
 		for($i=0; $i&lt;$width; $i=$i+rand(0,2)) {
 			for($j=0; $j&lt;$height; $j=$j+rand(0,2)) {
 				imagesetpixel($im, $i, $j, $dotcol);
 			}
 		}
-	  
+
 		//Adds Text
 		imagestring($im, $font, $charwidth, $charheight/2, $text, $fcol);
-	  
+
 		/*
 		 //Adds Horizontal lines
 		 for($j=0; $j&lt;$height*$size; $j=$j+rand(2,6)) {
 		 imageline($im2, 0, $j, $width*$size, $j, $linecol);
 		 }
 		 */
-	  
+
 		/*
 		 //Adds Vertical lines
 		 for($i=0; $i&lt;$width*$size; $i=$i+rand(1,19)) {
 		 imageline($im2, $i, 0, $i, $height*$size, $linecol);
 		 }
 		 */
-	  
+
 		//Adds horizontal dots
 		for($i=0; $i&lt;$width*$size; $i++) {
 			for($j=0; $j&lt;$height*$size; $j++) {
@@ -130,20 +129,20 @@ class captcha {
 				if ($col!=$bcol) imagesetpixel($im2, $i, $j, $col);
 			}
 		}
-	  
+
 		//Adds more horizontal dots
 		for($j=0; $j&lt;$height*$size; $j=$j+rand(2,5)) {
 			for($i=0; $i&lt;$width*$size; $i=$i+rand(2,5)) {
 				imagesetpixel($im2, $i, $j, $dotcol2);
 			}
 		}
-	  
+
 		//Adds the same number of vertical lines as chars
 		$start = rand(0, 10);
 		for($a = 1; $a &lt; strlen($text); $a++) {
 			imageline($im2, $start+$a*30, 0, $start+$a*30, $height*$size, imagecolorallocate($im2, rand(90,120), rand(90,120), rand(90,120)));
 		}
-	  
+
 		//Adds three polygons to radom places
 		for($a = 1; $a &lt; 4; $a++) {
 			imagepolygon(
@@ -162,15 +161,15 @@ class captcha {
 			ImageColorAllocate($im2, rand(60, 120),rand(60, 120),rand(60, 120))
 			);
 		};
-	  
+
 		//Create final png file
 		imagepng($im2, $file)
 		or trigger_error('Couldn\'t create CAPTCHA PNG: '. $file, E_USER_WARNING);
-	  
+
 		//Destroy the copies
 		imagedestroy($im);
 		imagedestroy($im2);
-		
+
 		return $text;
 	}
 </diff>
      <filename>libraries/captcha.php</filename>
    </modified>
    <modified>
      <diff>@@ -1,8 +1,8 @@
 &lt;?php
 /**
- * Core
+ * Controller
  *
- * This is the parent class for all controllers. Controller must extend this
+ * This is the parent class for all controllers. Controllers must extend this
  * class. If you want, you can also extend this class with another class which
  * your controllers can then extend.
  *
@@ -11,7 +11,7 @@
  * @copyright	Copyright (c) 2009 MicroMVC
  * @license		http://www.gnu.org/licenses/gpl-3.0.html
  * @link		http://micromvc.com
- * @version		1.0.1 &lt;5/31/2009&gt;
+ * @version		1.1.0 &lt;7/7/2009&gt;
  ********************************** 80 Columns *********************************
  */
 class controller {
@@ -146,19 +146,22 @@ class controller {
 	 */
 	public function load_config($name=null, $module = FALSE) {
 
-		//Only load once
-		if(!empty($this-&gt;config[$name])) {
-			return $this-&gt;config[$name];
-		}
-
 		//Is this a module's config -or a site config?
 		$path = ($module ? MODULE_PATH. $module. DS : SITE_PATH). 'config'. DS. $name. '.php';
 
 		//include the config
 		require($path);
 
-		//Set the values in our config array and return
-		return $this-&gt;config[$name] = $$name;
+		//If this element already exists - mearge the new array in (overwritting as needed)
+		if( ! empty($this-&gt;config[$name])) {
+			$this-&gt;config[$name] = array_merge($this-&gt;config[$name], $$name);
+
+		} else { //Set the values in our config array
+			$this-&gt;config[$name] = $$name;
+		}
+
+		//Return new config array
+		return $this-&gt;config[$name];
 
 	}
 
@@ -176,7 +179,7 @@ class controller {
 		load_class('db', LIBRARY_PATH, NULL, FALSE);
 
 		//Load the config for this database
-		$config = $this-&gt;config('database');
+		$config = $this-&gt;load_config('database');
 
 		//Create a new instance of the database child class &quot;mysql&quot;
 		$this-&gt;db = load_class($config['type'], NULL, $config);</diff>
      <filename>libraries/controller.php</filename>
    </modified>
    <modified>
      <diff>@@ -64,7 +64,7 @@
  * @copyright	Copyright (c) 2009 MicroMVC
  * @license		http://www.gnu.org/licenses/gpl-3.0.html
  * @link		http://micromvc.com
- * @version		1.0.1 &lt;5/31/2009&gt;
+ * @version		1.1.0 &lt;7/7/2009&gt;
  ********************************** 80 Columns *********************************
  */
 
@@ -990,6 +990,22 @@ class db {
 	}
 
 
+	/**
+	 * Wrapper for the PDO exec function which allows us to log the query
+	 * @param $sql
+	 * @return mixed
+	 */
+	public function exec($sql = NULL) {
+
+		//Add the query to the list
+		if($this-&gt;log_queries) {
+			$this-&gt;queries[] = $sql;
+		}
+
+		return $this-&gt;pdo-&gt;exec($sql);
+	}
+
+
 	/*
 	 * Run the PDO::query() method and return results
 	 */
@@ -1117,6 +1133,16 @@ class db {
 		return $this-&gt;last_query();
 	}
 
+
+	/*
+	 * Print out all of the queries run using &lt;pre&gt; tags
+	 */
+	public function print_queries() {
+		foreach($this-&gt;queries as $query) {
+			print '&lt;pre&gt;'. str_replace(&quot;\t&quot;, '', $query). '&lt;/pre&gt;'. &quot;\n\n&quot;;
+		}
+	}
+
 }
 
 </diff>
      <filename>libraries/db.php</filename>
    </modified>
    <modified>
      <diff>@@ -9,7 +9,7 @@
  * @copyright	Copyright (c) 2009 MicroMVC
  * @license		http://www.gnu.org/licenses/gpl-3.0.html
  * @link		http://micromvc.com
- * @version		1.0.1 &lt;5/31/2009&gt;
+ * @version		1.1.0 &lt;7/7/2009&gt;
  ********************************** 80 Columns *********************************
  */
 class hooks {
@@ -137,7 +137,7 @@ class hooks {
 	public function run_hook($hook = NULL, $data = NULL) {
 
 		//If it is NOT a hook config
-		if (!is_array($hook)) {
+		if (!is_array($hook) OR empty($hook)) {
 			return $data;
 		}
 
@@ -152,7 +152,7 @@ class hooks {
 		}
 
 		// Set each value to avoid php notices
-		foreach(array('class', 'function', 'file', 'path') as $type) {
+		foreach(array('class', 'function', 'file', 'path', 'module') as $type) {
 			$$type = empty($hook[$type]) ? NULL : $hook[$type];
 		}
 
@@ -162,11 +162,13 @@ class hooks {
 
 		//If we are missing a lot of stuff...
 		if (!$class &amp;&amp; !$function) {
+			trigger_error('Trying to run a Hook with no class or function.');
 			return $data;
 		}
 
 		//If a function is being called we HAVE TO HAVE a file name!
 		if (!$class &amp;&amp; (!$file &amp;&amp; $function)) {
+			trigger_error('Cannot run the '. $function. ' hook without a file');
 			return $data;
 		}
 
@@ -205,7 +207,7 @@ class hooks {
 		} else { //Else just run the function
 
 			//If the function does not alreay exist
-			if (!function_exists($function)) {
+			if ( ! function_exists($function)) {
 				require_once($path. $file. '.php');
 			}
 </diff>
      <filename>libraries/hooks.php</filename>
    </modified>
    <modified>
      <diff>@@ -9,7 +9,7 @@
  * @copyright	Copyright (c) 2009 MicroMVC
  * @license		http://www.gnu.org/licenses/gpl-3.0.html
  * @link		http://micromvc.com
- * @version		1.0.1 &lt;5/31/2009&gt;
+ * @version		1.1.0 &lt;7/7/2009&gt;
  ********************************** 80 Columns *********************************
  */
 class routes {</diff>
      <filename>libraries/routes.php</filename>
    </modified>
    <modified>
      <diff>@@ -20,7 +20,7 @@
  * @copyright	Copyright (c) 2009 MicroMVC
  * @license		http://www.gnu.org/licenses/gpl-3.0.html
  * @link		http://micromvc.com
- * @version		1.0.1 &lt;5/31/2009&gt;
+ * @version		1.1.0 &lt;7/7/2009&gt;
  ********************************** 80 Columns *********************************
  */
 
@@ -43,7 +43,7 @@ class twitter_api {
 	 * in case of abuse. Include your email.
 	 * @var string
 	 */
-	var $user_agent = SITE_NAME;
+	var $user_agent = DOMAIN;
 
 	/**
 	 * Can be set to JSON or XML - JSON is faster though...
@@ -85,7 +85,7 @@ class twitter_api {
 	 * Setup the Twitter Request Options
 	 */
 	function setup($options=array()) {
-			
+
 		/* [Options]
 		 * username		Your Twitter Username
 		 * password		Your Twitter Password</diff>
      <filename>libraries/twitter_api.php</filename>
    </modified>
    <modified>
      <diff>@@ -11,7 +11,7 @@
  * @copyright	Copyright (c) 2009 MicroMVC
  * @license		http://www.gnu.org/licenses/gpl-3.0.html
  * @link		http://micromvc.com
- * @version		1.0.1 &lt;5/31/2009&gt;
+ * @version		1.1.0 &lt;7/7/2009&gt;
  ********************************** 80 Columns *********************************
  */
 class validation {
@@ -85,7 +85,7 @@ class validation {
 
 		//Check each form element
 		foreach($config as $field =&gt; $rules) {
-			
+
 			//Break apart rules
 			if(strpos($rules, '|') !== FALSE) {
 				$rules = explode('|', $rules);
@@ -111,10 +111,10 @@ class validation {
 
 					//Fetch the function arguments
 					preg_match('/([a-z0-9_]+)\[(.*?)\]/i', $rule, $matches);
-						
+
 					//Fetch the rule name
 					$rule = $matches[1];
-						
+
 					//Get the params
 					$params = $matches[2];
 
@@ -165,9 +165,9 @@ class validation {
 			//Now that we are done working with the data - save it
 			$_POST[$field] = $data;
 		}
-		
+
 		//print_pre($_POST);
-		
+
 		//If no errors then we are good!
 		if(empty($this-&gt;errors)) {
 			return TRUE;
@@ -351,7 +351,7 @@ class validation {
 
 	/**
 	 * Check to see if the email entered is valid
-	 * 
+	 *
 	 * @param $field
 	 * @param $data
 	 * @return boolean
@@ -360,7 +360,7 @@ class validation {
 		if(valid_email($data)) {
 			return TRUE;
 		}
-		
+
 		//Set the error
 		$this-&gt;errors[$field] = sprintf($this-&gt;error_messages['valid_email'], ucwords($field));
 		return FALSE;</diff>
      <filename>libraries/validation.php</filename>
    </modified>
    <modified>
      <diff>@@ -2,39 +2,20 @@
 /*
  * Run on system startup
  */
-$hooks['startup'][] = array();
+$hooks['system_startup'][] = array();
 
+/*
+ * Run after the controller is loaded
+ */
+$hooks['post_constructor'][] = array();
 
-//Call a simple function from a hook
-$hooks['my_first_hook'] = array(
-	'function'	=&gt; 'hook_test',
-	'file'		=&gt; 'hook_test',
-);
-
-
-
-//Call a method of a class from a hook
-$hooks['my_second_hook'][] = array(
-	'class'		=&gt; 'my_second_hook',	//Name of class to find function in
-	'function'	=&gt; 'filter',			//The method to call
-	'file'		=&gt; 'my_second_hook',	//File that contains the class
-);
-
-//Then call this hook before returning the data
-$hooks['my_second_hook'][] = array(
-	'class'	=&gt; 'my_second_hook',	//Name of object to find function in
-	'function'	=&gt; 'say',
-);
-
-//Then call this hook before returning the data
-$hooks['my_second_hook'][] = array(
-	'class'		=&gt; 'my_second_hook',	//Name of class to find function in
-	'function'	=&gt; 'speak',
-);
-
+/**
+ * Run after the method is called, but before rendering page
+ */
+$hooks['post_method'] = array();
 
-//Then call this hook before returning the data
-$hooks['my_second_hook'][] = array(
-	'class'		=&gt; 'my_second_hook',	//Name of class to find function in
-);
+/**
+ * Called after everything is done
+ */
+$hooks['system_shutdown'] = array();
 </diff>
      <filename>localhost/config/hooks.php</filename>
    </modified>
    <modified>
      <diff>@@ -2,18 +2,20 @@
 /**
  * Posts
  *
- * Example of a &quot;post&quot; system that fills a table with several rows useing a 
+ * Example of a &quot;post&quot; system that fills a table with several rows useing a
  * model. Then it prints out those rows with a view. Also see &quot;posts_model.php&quot;
+ * This model uses auto-generated queries as well as hand written SQL to show
+ * how both work.
  *
  * @package		MicroMVC
  * @author		David Pennington
  * @copyright	Copyright (c) 2009 MicroMVC
  * @license		http://www.gnu.org/licenses/gpl-3.0.html
  * @link		http://micromvc.com
- * @version		1.0.1 &lt;5/31/2009&gt;
+ * @version		1.1.0 &lt;7/7/2009&gt;
  ********************************** 80 Columns *********************************
  */
-class posts extends core {
+class posts extends controller {
 
 	function __construct($config=null) {
 
@@ -22,35 +24,38 @@ class posts extends core {
 
 		//Load the database
 		$this-&gt;load_database();
-		
+
 		//Load the Model for this controller
-		$this-&gt;load('posts_model', 'posts', null, 'models');
+		$this-&gt;model('posts_model', NULL, 'posts');
 
+		//Check to see if the &quot;posts&quot; table is installed
+		$this-&gt;posts-&gt;check_install();
 	}
 
+
 	//Show the lastest posts
 	function index() {
 
 		//Count the total posts
 		$count = $this-&gt;db-&gt;count('posts');
-		
-		//If there are no rows 
+
+		//If there are no rows
 		if($count &lt; 1) {
 			//Add three rows
 			$this-&gt;posts-&gt;insert();
 		}
-		
+
 		//Fetch every row
 		$result = $this-&gt;posts-&gt;fetch();
 
 		//Setup dat for the view
 		$view_data = array(
-			'result' =&gt; $result, 
+			'result' =&gt; $result,
 			'count' =&gt; $count
 		);
-		
+
 		//Place in a view file
-		$this-&gt;data['content'] = $this-&gt;view('posts/posts', $view_data);
+		$this-&gt;views['content'] = $this-&gt;view('posts/posts', $view_data);
 
 	}
 </diff>
      <filename>localhost/controllers/posts.php</filename>
    </modified>
    <modified>
      <diff>@@ -9,7 +9,7 @@
  * @copyright	Copyright (c) 2009 MicroMVC
  * @license		http://www.gnu.org/licenses/gpl-3.0.html
  * @link		http://micromvc.com
- * @version		1.0.1 &lt;5/31/2009&gt;
+ * @version		1.1.0 &lt;7/7/2009&gt;
  ********************************** 80 Columns *********************************
  */
 
@@ -33,33 +33,6 @@ class welcome extends controller {
 
 
 	/*
-	 * Show an example of how hooks work
-	 */
-	function hooks() {
-
-		//Call a function from a hook
-		$this-&gt;views['content'] = $this-&gt;hooks-&gt;call('my_first_hook', true);
-
-		//Call two class methods from a hook
-		$this-&gt;views['content'] .= $this-&gt;hooks-&gt;call('my_second_hook', 'MY_WORD');
-
-	}
-
-
-	/*
-	 * Show an example of how to pass a value though the URI
-	 */
-	function say($word='You didn\'t say anything...') {
-
-		//Can't just let anything in! Someone might send a XSS...
-		$word = preg_replace(&quot;/([^a-z0-9_\-\. ]+)/i&quot;, ' ', trim($word));
-
-		//Set this as the layout content
-		$this-&gt;data['content'] = $word;
-	}
-
-
-	/*
 	 * Show and example of loading a API model and requesting data
 	 */
 	function twitter() {
@@ -74,7 +47,7 @@ class welcome extends controller {
 		);
 
 		//Load the twitter model and create object
-		$this-&gt;load('twitter_api', null, $options, 'libraries');
+		$this-&gt;library('twitter_api', $options);
 
 
 		//Get current user_timeline
@@ -89,7 +62,7 @@ class welcome extends controller {
 		$view['object'] = $object;
 
 		//Render the view
-		$this-&gt;data['content'] = $this-&gt;view('welcome/twitter', $view);
+		$this-&gt;views['content'] = $this-&gt;view('welcome/twitter', $view);
 
 	}
 }
\ No newline at end of file</diff>
      <filename>localhost/controllers/welcome.php</filename>
    </modified>
    <modified>
      <diff>@@ -9,12 +9,47 @@
  * @copyright	Copyright (c) 2009 MicroMVC
  * @license		http://www.gnu.org/licenses/gpl-3.0.html
  * @link		http://micromvc.com
- * @version		1.0.0 &lt;2/20/2009&gt;
+ * @version		1.1.0 &lt;7/7/2009&gt;
  ********************************** 80 Columns *********************************
  */
 class posts_model extends base {
 
 
+	//Check to see if the table exists - install it if not!
+	function check_install() {
+
+		//Get the database name
+		$dbname = preg_replace('/.+?dbname=([a-z0-9_]+)/i', '$1', $this-&gt;db-&gt;config['dns']);
+
+		//Create query
+		$sql = &quot;SELECT count(*) FROM information_schema.tables
+				WHERE table_schema = '&quot;. $dbname. &quot;' AND table_name = 'posts'&quot;;
+
+		//Send query
+		$result = $this-&gt;db-&gt;query($sql);
+
+		//If the table is not found
+		if( ! $result-&gt;fetchColumn()) {
+			$this-&gt;posts-&gt;create_table();
+		}
+	}
+
+
+	// Create the posts table
+	function create_table() {
+		$sql = 'CREATE TABLE IF NOT EXISTS `posts` (
+			  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+			  `title` varchar(255) NOT NULL,
+			  `author` int(10) unsigned NOT NULL,
+			  `text` text NOT NULL,
+			  PRIMARY KEY (`id`)
+			) ENGINE=MyISAM ;';
+
+		//Create the table
+		$this-&gt;db-&gt;exec($sql);
+	}
+
+
 	/**
 	 * Add some sample rows to the database
 	 * @return	void
@@ -23,7 +58,7 @@ class posts_model extends base {
 
 		//CREATE NEW ROWS IN THE TABLE
 		$data[] = array(
-			'title' =&gt; 'My First Post', 
+			'title' =&gt; 'My First Post',
 			'text' =&gt; 'Today I finished the beta of my new website!',
 			'author' =&gt; 'Me'
 		);
@@ -47,7 +82,7 @@ class posts_model extends base {
 
 	}
 
-	
+
 	/*
 	 * Get all the posts
 	 */</diff>
      <filename>localhost/models/posts_model.php</filename>
    </modified>
    <modified>
      <diff>@@ -1,2 +1,3 @@
 &lt;h2&gt;404 Page Not Found&lt;/h2&gt;
-&lt;p&gt;We're sorry, it appears the page you are looking for is missing.&lt;/p&gt;
\ No newline at end of file
+&lt;p&gt;We're sorry, it appears the page you are looking for is missing.&lt;/p&gt;
+&lt;?php print_pre($_SERVER); ?&gt;
\ No newline at end of file</diff>
      <filename>localhost/views/errors/404.php</filename>
    </modified>
    <modified>
      <diff>@@ -21,9 +21,9 @@
 			//Create a list of the menu links
 			$links = array(
 				'Welcome' =&gt; 'welcome/index',
-				'Hooks' =&gt; 'welcome/hooks',
-				'URI' =&gt; 'welcome/say',
-				'Twitter' =&gt; 'welcome/twitter',
+				'Hooks' =&gt; 'hooks',
+				'URI' =&gt; 'hooks/say',
+				'Twitter' =&gt; 'twitter',
 				'SQLite' =&gt; 'posts',
 			);
 </diff>
      <filename>localhost/views/layout.php</filename>
    </modified>
    <modified>
      <diff>@@ -7,3 +7,6 @@
 &lt;p&gt;&lt;?php print $row-&gt;text; ?&gt;&lt;/p&gt;
 
 &lt;?php } ?&gt;
+
+&lt;h2&gt;&lt;?php print count($this-&gt;db-&gt;queries); ?&gt; Database Queries Run&lt;/h2&gt;
+&lt;?php $this-&gt;db-&gt;print_queries(); ?&gt;</diff>
      <filename>localhost/views/posts/posts.php</filename>
    </modified>
    <modified>
      <diff>@@ -68,6 +68,12 @@ padding: 2em;
 border-top: 1px solid #ddd;
 }
 
+pre {
+background: #eee; 
+overflow: auto;
+padding: .5em;
+border: 1px solid #e1e1e1;
+}
 
 #footer { 
 border-top: 1px solid #eee; </diff>
      <filename>localhost/views/style.css</filename>
    </modified>
  </modified>
  <removed type="array">
    <removed>
      <filename>functions/hook_test.php</filename>
    </removed>
    <removed>
      <filename>libraries/my_second_hook.php</filename>
    </removed>
    <removed>
      <filename>localhost/views/welcome/twitter.php</filename>
    </removed>
  </removed>
  <parents type="array">
    <parent>
      <id>fd4bd18bd6ebb53b081b9f7186d1852be33b0766</id>
    </parent>
  </parents>
  <author>
    <name>Xeoncross</name>
    <email>david@xeoncross.com</email>
  </author>
  <url>http://github.com/Xeoncross/micromvc/commit/3c607f988718a1650e05e56b5e444b76ac97d1c4</url>
  <id>3c607f988718a1650e05e56b5e444b76ac97d1c4</id>
  <committed-date>2009-07-08T09:23:12-07:00</committed-date>
  <authored-date>2009-07-08T09:23:12-07:00</authored-date>
  <message>Moved the twitter and hooks example into modules to show how modules work. Also updated the posts controller and model to auto-install the posts table if not found.</message>
  <tree>f54534a4ccf23125be4b904d9c10d529c23057cf</tree>
  <committer>
    <name>Xeoncross</name>
    <email>david@xeoncross.com</email>
  </committer>
</commit>
