summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--system/database/DB_utility.php40
-rw-r--r--system/libraries/Controller.php21
-rw-r--r--system/libraries/Unit_test.php331
-rw-r--r--system/libraries/Zip.php152
-rw-r--r--user_guide/database/utilities.html28
-rw-r--r--user_guide/general/changelog.html27
-rw-r--r--user_guide/libraries/unit_testing.html2
-rw-r--r--user_guide/nav/nav.js3
8 files changed, 182 insertions, 422 deletions
diff --git a/system/database/DB_utility.php b/system/database/DB_utility.php
index e568bce02..2748a4407 100644
--- a/system/database/DB_utility.php
+++ b/system/database/DB_utility.php
@@ -216,7 +216,7 @@ class CI_DB_utility {
// --------------------------------------------------------------------
/**
- * Generate CVS from a query result object
+ * Generate CSV from a query result object
*
* @access public
* @param object The query result object
@@ -224,7 +224,7 @@ class CI_DB_utility {
* @param string The newline character - \n by default
* @return string
*/
- function cvs_from_result($query, $delim = "\t", $newline = "\n")
+ function csv_from_result($query, $delim = "\t", $newline = "\n")
{
if ( ! is_object($query) OR ! method_exists($query, 'field_names'))
{
@@ -502,6 +502,7 @@ class CI_DB_utility {
{
$obj->output->set_header('Content-Type: '.$mime);
$obj->output->set_header('Content-Disposition: inline; filename="'.$prefs['filename'].'.'.$ext[$prefs['format']].'"');
+ $obj->output->set_header('Content-Transfer-Encoding: binary');
$obj->output->set_header('Expires: 0');
$obj->output->set_header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
$obj->output->set_header('Pragma: public');
@@ -510,26 +511,27 @@ class CI_DB_utility {
{
$obj->output->set_header('Content-Type: '.$mime);
$obj->output->set_header('Content-Disposition: attachment; filename="'.$prefs['filename'].'.'.$ext[$prefs['format']].'"');
+ $obj->output->set_header('Content-Transfer-Encoding: binary');
$obj->output->set_header('Expires: 0');
$obj->output->set_header('Pragma: no-cache');
}
-
-
- // Write the file based on type
- switch ($prefs['format'])
- {
- case 'gzip' : $obj->output->set_output(gzencode($this->_backup($prefs)));
- break;
- case 'txt' : $obj->output->set_output($this->_backup($prefs));
- break;
- default :
- require BASEPATH.'libraries/Zip.php';
-
- $zip = new Zip;
- $zip->add_file($this->_backup($prefs), $prefs['filename'].'.sql');
- $obj->output->set_output($zip->output_zipfile());
- break;
- }
+
+
+ // Write the file based on type
+ switch ($prefs['format'])
+ {
+ case 'gzip' : $obj->output->set_output(gzencode($this->_backup($prefs)));
+ break;
+ case 'txt' : $obj->output->set_output($this->_backup($prefs));
+ break;
+ default :
+ require BASEPATH.'libraries/Zip.php';
+
+ $zip = new Zip;
+ $zip->add_file($this->_backup($prefs), $prefs['filename'].'.sql');
+ $obj->output->set_output($zip->output_zipfile());
+ break;
+ }
return TRUE;
}
diff --git a/system/libraries/Controller.php b/system/libraries/Controller.php
index 51f455023..c02074fca 100644
--- a/system/libraries/Controller.php
+++ b/system/libraries/Controller.php
@@ -80,6 +80,13 @@ class Controller extends CI_Base {
{
// Prep the class name
$class = strtolower(str_replace(EXT, '', $class));
+
+ // Bug fix for backward compat.
+ // Kill this at some point in the future
+ if ($class == 'unit_test')
+ {
+ $class = 'unit';
+ }
// Is this a class extension request?
if (substr($class, 0, 3) == 'my_')
@@ -168,9 +175,8 @@ class Controller extends CI_Base {
* @return null
*/
function _ci_init_class($class, $prefix = '', $config = NULL)
- {
+ {
// Is there an associated config file for this class?
-
if ($config == NULL)
{
if (file_exists(APPPATH.'config/'.$class.EXT))
@@ -185,22 +191,19 @@ class Controller extends CI_Base {
}
else
{
- $name = $prefix.ucfirst($class);
+ $name = $prefix.$class;
}
-
- $remap = array(
- 'Unit_test' => 'unit'
- );
$varname = ( ! isset($remap[$class])) ? $class : $remap[$class];
-
+ $varname = strtolower($varname);
+
// Instantiate the class
if ($config !== NULL)
{
$this->$varname = new $name($config);
}
else
- {
+ {
$this->$varname = new $name;
}
}
diff --git a/system/libraries/Unit_test.php b/system/libraries/Unit_test.php
deleted file mode 100644
index 0df78c253..000000000
--- a/system/libraries/Unit_test.php
+++ /dev/null
@@ -1,331 +0,0 @@
-<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
-/**
- * Code Igniter
- *
- * An open source application development framework for PHP 4.3.2 or newer
- *
- * @package CodeIgniter
- * @author Rick Ellis
- * @copyright Copyright (c) 2006, pMachine, Inc.
- * @license http://www.codeignitor.com/user_guide/license.html
- * @link http://www.codeigniter.com
- * @since Version 1.3.1
- * @filesource
- */
-
-// ------------------------------------------------------------------------
-
-/**
- * Unit Testing Class
- *
- * Simple testing class
- *
- * @package CodeIgniter
- * @subpackage Libraries
- * @category UnitTesting
- * @author Rick Ellis
- * @link http://www.codeigniter.com/user_guide/libraries/uri.html
- */
-class CI_Unit {
-
- var $active = TRUE;
- var $results = array();
- var $strict = FALSE;
- var $_template = NULL;
- var $_template_rows = NULL;
-
- function CI_Unit()
- {
- log_message('debug', "Unit Testing Class Initialized");
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Run the tests
- *
- * Runs the supplied tests
- *
- * @access public
- * @param mixed
- * @param mixed
- * @param string
- * @return string
- */
- function run($test, $expected = TRUE, $test_name = 'undefined')
- {
- if ($this->active == FALSE)
- return;
-
- if (in_array($expected, array('is_string', 'is_bool', 'is_true', 'is_false', 'is_int', 'is_numeric', 'is_float', 'is_double', 'is_array', 'is_null'), TRUE))
- {
- $expected = str_replace('is_float', 'is_double', $expected);
- $result = ($expected($test)) ? TRUE : FALSE;
- $extype = str_replace(array('true', 'false'), 'bool', str_replace('is_', '', $expected));
- }
- else
- {
- if ($this->strict == TRUE)
- $result = ($test === $expected) ? TRUE : FALSE;
- else
- $result = ($test == $expected) ? TRUE : FALSE;
-
- $extype = gettype($expected);
- }
-
- $back = $this->_backtrace();
-
- $report[] = array (
- 'test_name' => $test_name,
- 'test_datatype' => gettype($test),
- 'res_datatype' => $extype,
- 'result' => ($result === TRUE) ? 'passed' : 'failed',
- 'file' => $back['file'],
- 'line' => $back['line']
- );
-
- $this->results[] = $report;
-
- return($this->report($this->result($report)));
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Generate a report
- *
- * Displays a table with the test data
- *
- * @access public
- * @return string
- */
- function report($result = array())
- {
- if (count($result) == 0)
- {
- $result = $this->result();
- }
-
- $this->_parse_template();
-
- $r = '';
- foreach ($result as $res)
- {
- $table = '';
-
- foreach ($res as $key => $val)
- {
- $temp = $this->_template_rows;
- $temp = str_replace('{item}', $key, $temp);
- $temp = str_replace('{result}', $val, $temp);
- $table .= $temp;
- }
-
- $r .= str_replace('{rows}', $table, $this->_template);
- }
-
- return $r;
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Use strict comparison
- *
- * Causes the evaluation to use === rather then ==
- *
- * @access public
- * @param bool
- * @return null
- */
- function use_strict($state = TRUE)
- {
- $this->strict = ($state == FALSE) ? FALSE : TRUE;
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Make Unit testing active
- *
- * Enables/disables unit testing
- *
- * @access public
- * @param bool
- * @return null
- */
- function active($state = TRUE)
- {
- $this->active = ($state == FALSE) ? FALSE : TRUE;
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Result Array
- *
- * Returns the raw result data
- *
- * @access public
- * @return array
- */
- function result($results = array())
- {
- $obj =& get_instance();
- $obj->load->language('unit_test');
-
- if (count($results) == 0)
- {
- $results = $this->results;
- }
-
- $retval = array();
- foreach ($results as $result)
- {
- $temp = array();
- foreach ($result as $key => $val)
- {
- if (is_array($val))
- {
- foreach ($val as $k => $v)
- {
- if (FALSE !== ($line = $obj->lang->line(strtolower('ut_'.$v))))
- {
- $v = $line;
- }
- $temp[$obj->lang->line('ut_'.$k)] = $v;
- }
- }
- else
- {
- if (FALSE !== ($line = $obj->lang->line(strtolower('ut_'.$val))))
- {
- $val = $line;
- }
- $temp[$obj->lang->line('ut_'.$key)] = $val;
- }
- }
-
- $retval[] = $temp;
- }
-
- return $retval;
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Set the template
- *
- * This lets us set the template to be used to display results
- *
- * @access public
- * @params string
- * @return void
- */
- function set_template($template)
- {
- $this->_template = $template;
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Generate a backtrace
- *
- * This lets us show file names and line numbers
- *
- * @access private
- * @return array
- */
- function _backtrace()
- {
- if (function_exists('debug_backtrace'))
- {
- $back = debug_backtrace();
-
- $file = ( ! isset($back['1']['file'])) ? '' : $back['1']['file'];
- $line = ( ! isset($back['1']['line'])) ? '' : $back['1']['line'];
-
- return array('file' => $file, 'line' => $line);
- }
- return array('file' => 'Unknown', 'line' => 'Unknown');
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Get Default Template
- *
- * @access private
- * @return string
- */
- function _default_template()
- {
- $this->_template = '
- <div style="margin:15px;background-color:#ccc;">
- <table border="0" cellpadding="4" cellspacing="1" style="width:100%;">
- {rows}
- </table></div>';
-
- $this->_template_rows = '
- <tr>
- <td style="background-color:#fff;width:140px;font-size:12px;font-weight:bold;">{item}</td>
- <td style="background-color:#fff;font-size:12px;">{result}</td>
- </tr>
- ';
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Parse Template
- *
- * Harvests the data within the template {pseudo-variables}
- *
- * @access private
- * @return void
- */
- function _parse_template()
- {
- if ( ! is_null($this->_template_rows))
- {
- return;
- }
-
- if (is_null($this->_template))
- {
- $this->_default_template();
- return;
- }
-
- if ( ! preg_match("/\{rows\}(.*?)\{\/rows\}/si", $this->_template, $match))
- {
- $this->_default_template();
- return;
- }
-
- $this->_template_rows = $match['1'];
- $this->_template = str_replace($match['0'], '{rows}', $this->_template);
- }
-
-}
-// END Unit_test Class
-
-/**
- * Helper functions to test boolean true/false
- *
- *
- * @access private
- * @return bool
- */
-function is_true($test)
-{
- return (is_bool($test) AND $test === TRUE) ? TRUE : FALSE;
-}
-function is_false($test)
-{
- return (is_bool($test) AND $test === FALSE) ? TRUE : FALSE;
-}
-
-?> \ No newline at end of file
diff --git a/system/libraries/Zip.php b/system/libraries/Zip.php
index aa264386d..2ffed9fe2 100644
--- a/system/libraries/Zip.php
+++ b/system/libraries/Zip.php
@@ -18,9 +18,11 @@
/**
* Zip Compression Class
*
- * This class is based on a library aquired at Zend:
+ * This class is based on a library I found at Zend:
* http://www.zend.com/codex.php?id=696&single=1
*
+ * The original library is a little rough around the edges so I
+ * refactored it and added several additional methods -- Rick Ellis
*
* @package CodeIgniter
* @subpackage Libraries
@@ -28,12 +30,18 @@
* @author Rick Ellis
* @link http://www.codeigniter.com/user_guide/general/encryption.html
*/
-class Zip {
-
+class CI_Zip {
+
+ var $zipfile = '';
var $zipdata = array();
var $directory = array();
var $offset = 0;
- var $zipfile = '';
+
+ function CI_Zip()
+ {
+ log_message('debug', "Zip Compression Class Initialized");
+ }
+
/**
* Add Directory
@@ -41,13 +49,33 @@ class Zip {
* Lets you add a virtual directory into which you can place files.
*
* @access public
+ * @param mixed the directory name. Can be string or array
+ * @return void
+ */
+ function add_dir($directory)
+ {
+ foreach ((array)$directory as $dir)
+ {
+ if ( ! preg_match("|.+/$|", $dir))
+ {
+ $dir .= '/';
+ }
+
+ $this->_add_dir($dir);
+ }
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Add Directory
+ *
+ * @access private
* @param string the directory name
* @return void
*/
- function add_dir($dir)
+ function _add_dir($dir)
{
- $this->zipfile = '';
-
$dir = str_replace("\\", "/", $dir);
$this->zipdata[] = "\x50\x4b\x03\x04\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00"
@@ -78,27 +106,50 @@ class Zip {
$this->offset = $newoffset;
$this->directory[] = $record;
- }
-
+ }
+
// --------------------------------------------------------------------
/**
- * Add File
+ * Add Data to Zip
*
* Lets you add files to the archive. If the path is included
* in the filename it will be placed within a directory. Make
* sure you use add_dir() first to create the folder.
*
* @access public
- * @param string the file name
- * @param string the data to be encoded
+ * @param mixed
+ * @param string
* @return void
*/
- function add_file($filename, $data)
+ function add_data($filepath, $data = NULL)
{
- $this->zipfile = '';
+ if (is_array($filepath))
+ {
+ foreach ($filepath as $path => $data)
+ {
+ $this->_add_data($path, $data);
+ }
+ }
+ else
+ {
+ $this->_add_data($filepath, $data);
+ }
+ }
- $filename = str_replace("\\", "/", $filename);
+ // --------------------------------------------------------------------
+
+ /**
+ * Add Data to Zip
+ *
+ * @access private
+ * @param string the file name/path
+ * @param string the data to be encoded
+ * @return void
+ */
+ function _add_data($filepath, $data)
+ {
+ $filepath = str_replace("\\", "/", $filepath);
$oldlen = strlen($data);
$crc32 = crc32($data);
@@ -111,9 +162,9 @@ class Zip {
.pack('V', $crc32)
.pack('V', $newlen)
.pack('V', $oldlen)
- .pack('v', strlen($filename))
+ .pack('v', strlen($filepath))
.pack('v', 0)
- .$filename
+ .$filepath
.$gzdata
.pack('V', $crc32)
.pack('V', $newlen)
@@ -125,7 +176,7 @@ class Zip {
.pack('V', $crc32)
.pack('V', $newlen)
.pack('V', $oldlen)
- .pack('v', strlen($filename))
+ .pack('v', strlen($filepath))
.pack('v', 0)
.pack('v', 0)
.pack('v', 0)
@@ -134,26 +185,7 @@ class Zip {
.pack('V', $this->offset);
$this->offset = $newoffset;
- $this->directory[] = $record.$filename;
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Read the content of a file
- *
- * @access public
- * @param string the file path
- * @return string
- */
- function read_file($filepath)
- {
- if ( ! file_exists($filepath))
- {
- return FALSE;
- }
-
- return file_get_contents($filepath);
+ $this->directory[] = $record.$filepath;
}
// --------------------------------------------------------------------
@@ -166,11 +198,19 @@ class Zip {
*/
function get_zip()
{
+ // We cache the zip data so multiple calls
+ // do not require recompiling
if ($this->zipfile != '')
{
return $this->zipfile;
}
+ // Is there any data to return?
+ if (count($this->zipdata) == 0)
+ {
+ return FALSE;
+ }
+
$data = implode('', $this->zipdata);
$dir = implode('', $this->directory);
@@ -180,7 +220,7 @@ class Zip {
.pack('V', strlen($dir))
.pack('V', strlen($data))
."\x00\x00";
-
+
return $this->zipfile;
}
@@ -196,15 +236,15 @@ class Zip {
* @param string the data to be encoded
* @return bool
*/
- function write_file($filename, $data)
+ function write_zip($filepath)
{
- if ( ! ($fp = fopen($filename, "wb")))
+ if ( ! ($fp = fopen($filepath, "wb")))
{
return FALSE;
}
flock($fp, LOCK_EX);
- fwrite($fp, $data);
+ fwrite($fp, $this->get_zip());
flock($fp, LOCK_UN);
fclose($fp);
@@ -216,13 +256,12 @@ class Zip {
/**
* Download
*
- *
* @access public
* @param string the file name
* @param string the data to be encoded
* @return bool
*/
- function download($filename, $data)
+ function download($filename)
{
if (strstr($_SERVER['HTTP_USER_AGENT'], "MSIE"))
{
@@ -232,7 +271,7 @@ class Zip {
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header("Content-Transfer-Encoding: binary");
header('Pragma: public');
- header("Content-Length: ".strlen($data));
+ header("Content-Length: ".strlen($this->get_zip()));
}
else
{
@@ -241,10 +280,29 @@ class Zip {
header("Content-Transfer-Encoding: binary");
header('Expires: 0');
header('Pragma: no-cache');
- header("Content-Length: ".strlen($data));
+ header("Content-Length: ".strlen($this->get_zip()));
}
- echo $data;
+ echo $this->get_zip();
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Initialize Data
+ *
+ * Lets you clear current zip data. Useful if you need to create
+ * multiple zips with different data.
+ *
+ * @access public
+ * @return void
+ */
+ function clear_data()
+ {
+ $this->zipfile = '';
+ $this->zipdata = array();
+ $this->directory = array();
+ $this->offset = array();
}
}
diff --git a/user_guide/database/utilities.html b/user_guide/database/utilities.html
index 3af494482..3efa04f1d 100644
--- a/user_guide/database/utilities.html
+++ b/user_guide/database/utilities.html
@@ -48,7 +48,7 @@ window.onload = function() {
<a href="http://www.codeigniter.com/">Code Igniter Home</a> &nbsp;&#8250;&nbsp;
<a href="../index.html">User Guide Home</a> &nbsp;&#8250;&nbsp;
<a href="index.html">Database Library</a> &nbsp;&#8250;&nbsp;
-Database Utilities Class
+Database Utility Class
</td>
<td id="searchbox"><form method="get" action="http://www.google.com/search"><input type="hidden" name="as_sitesearch" id="as_sitesearch" value="www.codeigniter.com/user_guide/" />Search User Guide&nbsp; <input type="text" class="input" style="width:200px;" name="q" id="q" size="31" maxlength="255" value="" />&nbsp;<input type="submit" class="submit" name="sa" value="Go" /></form></td>
</tr>
@@ -62,28 +62,28 @@ Database Utilities Class
<!-- START CONTENT -->
<div id="content">
-<h1>Database Utilities Class</h1>
+<h1>Database Utility Class</h1>
-<p>The Database Utilities Class contains functions that help you manage your database.</p>
+<p>The Database Utility Class contains functions that help you manage your database.</p>
<h3>Table of Contents</h3>
<ul>
-<li><a href="#init">Initializing the Utilities Class</a></li>
+<li><a href="#init">Initializing the Utility Class</a></li>
<li><a href="#create">Creating a Database</a></li>
<li><a href="#drop">Dropping a Database</a></li>
<li><a href="#list">Listing your Databases</a></li>
<li><a href="#opttb">Optimizing your Tables</a></li>
<li><a href="#repair">Repairing your Databases</a></li>
<li><a href="#optdb">Optimizing your Database</a></li>
-<li><a href="#cvs">CVS Files from a Database Result</a></li>
+<li><a href="#csv">CSV Files from a Database Result</a></li>
<li><a href="#xml">XML Files from a Database Result</a></li>
<li><a href="#backup">Backing up your Database</a></li>
</ul>
<a name="init"></a>
-<h2>Initializing the Utilities Class</h2>
+<h2>Initializing the Utility Class</h2>
<p class="important"><strong>Important:</strong>&nbsp; This class must be initialized independently since it is a separate class from the main Database class.
More info below...</p>
@@ -184,10 +184,10 @@ if ($result !== FALSE)<br />
<p><strong>Note:</strong> Not all database platforms support table optimization.</p>
-<a name="cvs"></a>
-<h2>$this->dbutil->cvs_from_result($db_result)</h2>
+<a name="csv"></a>
+<h2>$this->dbutil->csv_from_result($db_result)</h2>
-<p>Permits you to generate a CVS file from a query result. The first parameter of the function must contain the result object from your query.
+<p>Permits you to generate a CSV file from a query result. The first parameter of the function must contain the result object from your query.
Example:</p>
<code>
@@ -195,7 +195,7 @@ $this->load->dbutil();<br />
<br />
$query = $this->db->query("SELECT * FROM mytable");<br />
<br />
-echo $this->dbutil->cvs_from_result($query);
+echo $this->dbutil->csv_from_result($query);
</code>
<p>The second and third parameters allows you to
@@ -205,10 +205,10 @@ set the delimiter and newline character. By default tabs are used as the delimi
$delimiter = ",";<br />
$newline = "\r\n";<br />
<br />
-echo $this->dbutil->cvs_from_result($query, $delimiter, $newline);
+echo $this->dbutil->csv_from_result($query, $delimiter, $newline);
</code>
-<p class="important"><strong>Important:</strong>&nbsp; This function will NOT write the CVS file for you. It simply creates the CVS layout.
+<p class="important"><strong>Important:</strong>&nbsp; This function will NOT write the CSV file for you. It simply creates the CSV layout.
If you need to write the file use the <a href="../helpers/file_helper.html">File Helper</a>.</p>
@@ -230,10 +230,10 @@ $config = array (<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';tab'&nbsp;&nbsp;&nbsp;&nbsp;=> "\t"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;);<br />
<br />
-echo $this->dbutil->cvs_from_result($query, $config);
+echo $this->dbutil->xml_from_result($query, $config);
</code>
-<p class="important"><strong>Important:</strong>&nbsp; This function will NOT write the CVS file for you. It simply creates the CVS layout.
+<p class="important"><strong>Important:</strong>&nbsp; This function will NOT write the XML file for you. It simply creates the XML layout.
If you need to write the file use the <a href="../helpers/file_helper.html">File Helper</a>.</p>
diff --git a/user_guide/general/changelog.html b/user_guide/general/changelog.html
index 4d4c53778..aab14d516 100644
--- a/user_guide/general/changelog.html
+++ b/user_guide/general/changelog.html
@@ -63,6 +63,33 @@ Change Log
<h1>Change Log</h1>
+<h2>Version 1.5.0</h2>
+<p>Release Date: Ocotber 15, 2006</p>
+
+<ul>
+<li>Added <a href="../database/utilities.html">DB utility class</a>, permitting DB backups, generating CVS or XML files, and various other functions.</li>
+<li>Added <a href="../database/caching.html">DB Caching class</a> permitting queries to be cached.</li>
+<li>Added <a href="../database/transactions.html">transaction support</a> to the database classes.</li>
+<li>Added relationship capability to the database active record class</li>
+<li>Added the ability to <a href="creating_libraries.html">extend libraries</a> and <a href="core_classes.html">extend core classes</a>, in addition to being able to replace them.</li>
+<li>Added support for storing <a href="models.html">models within sub-folders</a>.</li>
+<li>Added simple_query() function to the database classes</li>
+<li>Added $query->free_result();</li>
+<li>Added $query->field_names() function</li>
+<li>Added $this->db->platform() function</li>
+<li>Added "is_numeric" to validation</li>
+
+<li><strong>Deprecated "init" folder</strong>. Initialization happens automatically now. <a href="creating_libraries.html">Please see documentation</a>.</li>
+<li><strong>Deprecated</strong> $this->db->field_names() USE $this->db->list_fields()</li>
+<li><strong>Deprecated</strong> $this->load->library('unit_test'). USE $this->load->library('unit')</li>
+
+
+
+</ul>
+
+
+
+
<h2>Version 1.4.1</h2>
<p>Release Date: September 21, 2006</p>
diff --git a/user_guide/libraries/unit_testing.html b/user_guide/libraries/unit_testing.html
index f7b1f2050..5e9cdd233 100644
--- a/user_guide/libraries/unit_testing.html
+++ b/user_guide/libraries/unit_testing.html
@@ -76,7 +76,7 @@ to determine if it is producing the correct data type and result.
<p>Like most other classes in Code Igniter, the Unit Test class is initialized in your controller using the <dfn>$this->load->library</dfn> function:</p>
-<code>$this->load->library('unit_test');</code>
+<code>$this->load->library('unit');</code>
<p>Once loaded, the Unit Test object will be available using: <dfn>$this->unit</dfn></p>
diff --git a/user_guide/nav/nav.js b/user_guide/nav/nav.js
index d7e3fa8cb..fa8a673f4 100644
--- a/user_guide/nav/nav.js
+++ b/user_guide/nav/nav.js
@@ -21,7 +21,7 @@ function create_menu(basepath)
'<li><a href="'+base+'installation/downloads.html">Downloading Code Igniter</a></li>' +
'<li><a href="'+base+'installation/index.html">Installation Instructions</a></li>' +
'<li><a href="'+base+'installation/upgrading.html">Upgrading from a Previous Version</a></li>' +
- '<li><a href="'+base+'troubleshooting.html">Troubleshooting</a></li>' +
+ '<li><a href="'+base+'installation/troubleshooting.html">Troubleshooting</a></li>' +
'</ul>' +
'<h3>Introduction</h3>' +
@@ -83,6 +83,7 @@ function create_menu(basepath)
'<li><a href="'+base+'libraries/uri.html">URI Class</a></li>' +
'<li><a href="'+base+'libraries/validation.html">Validation Class</a></li>' +
'<li><a href="'+base+'libraries/xmlrpc.html">XML-RPC Class</a></li>' +
+ '<li><a href="'+base+'libraries/zip.html">Zip Encoding Class</a></li>' +
'</ul>' +
'</td><td class="td_sep" valign="top">' +