Merge pull request #819 from narfbg/develop-migration

Improve the Migration library
diff --git a/application/config/database.php b/application/config/database.php
index 58eec4b..880773d 100644
--- a/application/config/database.php
+++ b/application/config/database.php
@@ -41,7 +41,7 @@
 |	['username'] The username used to connect to the database
 |	['password'] The password used to connect to the database
 |	['database'] The name of the database you want to connect to
-|	['dbdriver'] The database type. ie: mysql.  Currently supported:
+|	['dbdriver'] The database type. e.g.: mysql.  Currently supported:
 				 mysql, mysqli, pdo, postgre, odbc, mssql, sqlite, oci8
 |	['dbprefix'] You can add an optional prefix, which will be added
 |				 to the table name when using the  Active Record class
diff --git a/system/database/DB_active_rec.php b/system/database/DB_active_rec.php
index 41950e7..412febf 100644
--- a/system/database/DB_active_rec.php
+++ b/system/database/DB_active_rec.php
@@ -830,9 +830,10 @@
 	 *
 	 * @param	string
 	 * @param	string	direction: asc or desc
+	 * @param	bool	enable field name escaping
 	 * @return	object
 	 */
-	public function order_by($orderby, $direction = '')
+	public function order_by($orderby, $direction = '', $escape = TRUE)
 	{
 		if (strtolower($direction) == 'random')
 		{
@@ -845,7 +846,7 @@
 		}
 
 
-		if (strpos($orderby, ',') !== FALSE)
+		if ((strpos($orderby, ',') !== FALSE) && ($escape === TRUE))
 		{
 			$temp = array();
 			foreach (explode(',', $orderby) as $part)
@@ -863,7 +864,10 @@
 		}
 		else if ($direction != $this->_random_keyword)
 		{
-			$orderby = $this->_protect_identifiers($orderby);
+			if ($escape === TRUE)
+			{
+				$orderby = $this->_protect_identifiers($orderby);
+			}
 		}
 
 		$orderby_statement = $orderby.$direction;
diff --git a/system/database/drivers/oci8/oci8_result.php b/system/database/drivers/oci8/oci8_result.php
index 3ec71a9..f325592 100644
--- a/system/database/drivers/oci8/oci8_result.php
+++ b/system/database/drivers/oci8/oci8_result.php
@@ -57,11 +57,11 @@
 		if ($this->num_rows === 0 && count($this->result_array()) > 0)
 		{
 			$this->num_rows = count($this->result_array());
-			@oci_execute($this->stmt_id);
+			@oci_execute($this->stmt_id, OCI_DEFAULT);
 
 			if ($this->curs_id)
 			{
-				@oci_execute($this->curs_id);
+				@oci_execute($this->curs_id, OCI_DEFAULT);
 			}
 		}
 
diff --git a/system/libraries/Calendar.php b/system/libraries/Calendar.php
index f5ef4d5..605765b 100644
--- a/system/libraries/Calendar.php
+++ b/system/libraries/Calendar.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
 /**
  * CodeIgniter
  *
  * An open source application development framework for PHP 5.1.6 or newer
  *
  * NOTICE OF LICENSE
- * 
+ *
  * Licensed under the Open Software License version 3.0
- * 
+ *
  * This source file is subject to the Open Software License (OSL 3.0) that is
  * bundled with this package in the files license.txt / license.rst.  It is
  * also available through the world wide web at this URL:
@@ -40,15 +40,15 @@
  */
 class CI_Calendar {
 
-	var $CI;
-	var $lang;
-	var $local_time;
-	var $template		= '';
-	var $start_day		= 'sunday';
-	var $month_type		= 'long';
-	var $day_type		= 'abr';
-	var $show_next_prev	= FALSE;
-	var $next_prev_url	= '';
+	private $CI;
+	public $lang;
+	public $local_time;
+	public $template		= '';
+	public $start_day		= 'sunday';
+	public $month_type		= 'long';
+	public $day_type		= 'abr';
+	public $show_next_prev	= FALSE;
+	public $next_prev_url	= '';
 
 	/**
 	 * Constructor
@@ -85,7 +85,7 @@
 	 * @param	array	config preferences
 	 * @return	void
 	 */
-	function initialize($config = array())
+	public function initialize($config = array())
 	{
 		foreach ($config as $key => $val)
 		{
@@ -107,23 +107,30 @@
 	 * @param	array	the data to be shown in the calendar cells
 	 * @return	string
 	 */
-	function generate($year = '', $month = '', $data = array())
+	public function generate($year = '', $month = '', $data = array())
 	{
 		// Set and validate the supplied month/year
 		if ($year == '')
-			$year  = date("Y", $this->local_time);
+		{
+			$year  = date('Y', $this->local_time);
+		}
+		elseif (strlen($year) === 1)
+		{
+			$year = '200'.$year;
+		}
+		elseif (strlen($year) === 2)
+		{
+			$year = '20'.$year;
+		}
 
 		if ($month == '')
-			$month = date("m", $this->local_time);
-
-		if (strlen($year) == 1)
-			$year = '200'.$year;
-
-		if (strlen($year) == 2)
-			$year = '20'.$year;
-
-		if (strlen($month) == 1)
+		{
+			$month = date('m', $this->local_time);
+		}
+		elseif (strlen($month) === 1)
+		{
 			$month = '0'.$month;
+		}
 
 		$adjusted_date = $this->adjust_date($month, $year);
 
@@ -149,9 +156,9 @@
 
 		// Set the current month/year/day
 		// We use this to determine the "today" date
-		$cur_year	= date("Y", $this->local_time);
-		$cur_month	= date("m", $this->local_time);
-		$cur_day	= date("j", $this->local_time);
+		$cur_year	= date('Y', $this->local_time);
+		$cur_month	= date('m', $this->local_time);
+		$cur_day	= date('j', $this->local_time);
 
 		$is_current_month = ($cur_year == $year AND $cur_month == $month) ? TRUE : FALSE;
 
@@ -159,12 +166,7 @@
 		$this->parse_template();
 
 		// Begin building the calendar output
-		$out = $this->temp['table_open'];
-		$out .= "\n";
-
-		$out .= "\n";
-		$out .= $this->temp['heading_row_start'];
-		$out .= "\n";
+		$out = $this->temp['table_open']."\n\n".$this->temp['heading_row_start']."\n";
 
 		// "previous" month link
 		if ($this->show_next_prev == TRUE)
@@ -173,18 +175,16 @@
 			$this->next_prev_url = preg_replace("/(.+?)\/*$/", "\\1/",  $this->next_prev_url);
 
 			$adjusted_date = $this->adjust_date($month - 1, $year);
-			$out .= str_replace('{previous_url}', $this->next_prev_url.$adjusted_date['year'].'/'.$adjusted_date['month'], $this->temp['heading_previous_cell']);
-			$out .= "\n";
+			$out .= str_replace('{previous_url}', $this->next_prev_url.$adjusted_date['year'].'/'.$adjusted_date['month'], $this->temp['heading_previous_cell'])."\n";
 		}
 
 		// Heading containing the month/year
 		$colspan = ($this->show_next_prev == TRUE) ? 5 : 7;
 
-		$this->temp['heading_title_cell'] = str_replace('{colspan}', $colspan, $this->temp['heading_title_cell']);
-		$this->temp['heading_title_cell'] = str_replace('{heading}', $this->get_month_name($month)."&nbsp;".$year, $this->temp['heading_title_cell']);
+		$this->temp['heading_title_cell'] = str_replace('{colspan}', $colspan,
+								str_replace('{heading}', $this->get_month_name($month).'&nbsp;'.$year, $this->temp['heading_title_cell']));
 
-		$out .= $this->temp['heading_title_cell'];
-		$out .= "\n";
+		$out .= $this->temp['heading_title_cell']."\n";
 
 		// "next" month link
 		if ($this->show_next_prev == TRUE)
@@ -193,14 +193,9 @@
 			$out .= str_replace('{next_url}', $this->next_prev_url.$adjusted_date['year'].'/'.$adjusted_date['month'], $this->temp['heading_next_cell']);
 		}
 
-		$out .= "\n";
-		$out .= $this->temp['heading_row_end'];
-		$out .= "\n";
-
-		// Write the cells containing the days of the week
-		$out .= "\n";
-		$out .= $this->temp['week_row_start'];
-		$out .= "\n";
+		$out .= "\n".$this->temp['heading_row_end']."\n\n"
+			// Write the cells containing the days of the week
+			.$this->temp['week_row_start']."\n";
 
 		$day_names = $this->get_day_names();
 
@@ -209,33 +204,31 @@
 			$out .= str_replace('{week_day}', $day_names[($start_day + $i) %7], $this->temp['week_day_cell']);
 		}
 
-		$out .= "\n";
-		$out .= $this->temp['week_row_end'];
-		$out .= "\n";
+		$out .= "\n".$this->temp['week_row_end']."\n";
 
 		// Build the main body of the calendar
 		while ($day <= $total_days)
 		{
-			$out .= "\n";
-			$out .= $this->temp['cal_row_start'];
-			$out .= "\n";
+			$out .= "\n".$this->temp['cal_row_start']."\n";
 
 			for ($i = 0; $i < 7; $i++)
 			{
-				$out .= ($is_current_month == TRUE AND $day == $cur_day) ? $this->temp['cal_cell_start_today'] : $this->temp['cal_cell_start'];
+				$out .= ($is_current_month === TRUE AND $day == $cur_day) ? $this->temp['cal_cell_start_today'] : $this->temp['cal_cell_start'];
 
 				if ($day > 0 AND $day <= $total_days)
 				{
 					if (isset($data[$day]))
 					{
 						// Cells with content
-						$temp = ($is_current_month == TRUE AND $day == $cur_day) ? $this->temp['cal_cell_content_today'] : $this->temp['cal_cell_content'];
-						$out .= str_replace('{day}', $day, str_replace('{content}', $data[$day], $temp));
+						$temp = ($is_current_month === TRUE AND $day == $cur_day) ?
+								$this->temp['cal_cell_content_today'] : $this->temp['cal_cell_content'];
+						$out .= str_replace(array('{content}', '{day}'), array($data[$day], $day), $temp);
 					}
 					else
 					{
 						// Cells with no content
-						$temp = ($is_current_month == TRUE AND $day == $cur_day) ? $this->temp['cal_cell_no_content_today'] : $this->temp['cal_cell_no_content'];
+						$temp = ($is_current_month === TRUE AND $day == $cur_day) ?
+								$this->temp['cal_cell_no_content_today'] : $this->temp['cal_cell_no_content'];
 						$out .= str_replace('{day}', $day, $temp);
 					}
 				}
@@ -245,17 +238,14 @@
 					$out .= $this->temp['cal_cell_blank'];
 				}
 
-				$out .= ($is_current_month == TRUE AND $day == $cur_day) ? $this->temp['cal_cell_end_today'] : $this->temp['cal_cell_end'];					
+				$out .= ($is_current_month === TRUE AND $day == $cur_day) ? $this->temp['cal_cell_end_today'] : $this->temp['cal_cell_end'];
 				$day++;
 			}
 
-			$out .= "\n";
-			$out .= $this->temp['cal_row_end'];
-			$out .= "\n";
+			$out .= "\n".$this->temp['cal_row_end']."\n";
 		}
 
-		$out .= "\n";
-		$out .= $this->temp['table_close'];
+		$out .= "\n".$this->temp['table_close'];
 
 		return $out;
 	}
@@ -272,7 +262,7 @@
 	 * @param	integer	the month
 	 * @return	string
 	 */
-	function get_month_name($month)
+	public function get_month_name($month)
 	{
 		if ($this->month_type == 'short')
 		{
@@ -287,7 +277,7 @@
 
 		if ($this->CI->lang->line($month) === FALSE)
 		{
-			return ucfirst(str_replace('cal_', '', $month));
+			return ucfirst(substr($month, 4));
 		}
 
 		return $this->CI->lang->line($month);
@@ -305,10 +295,12 @@
 	 * @param	string
 	 * @return	array
 	 */
-	function get_day_names($day_type = '')
+	public function get_day_names($day_type = '')
 	{
 		if ($day_type != '')
+		{
 			$this->day_type = $day_type;
+		}
 
 		if ($this->day_type == 'long')
 		{
@@ -324,9 +316,9 @@
 		}
 
 		$days = array();
-		foreach ($day_names as $val)
+		for ($i = 0, $c = count($day_names); $i < $c; $i++)
 		{
-			$days[] = ($this->CI->lang->line('cal_'.$val) === FALSE) ? ucfirst($val) : $this->CI->lang->line('cal_'.$val);
+			$days[] = ($this->CI->lang->line('cal_'.$day_names[$i]) === FALSE) ? ucfirst($day_names[$i]) : $this->CI->lang->line('cal_'.$day_names[$i]);
 		}
 
 		return $days;
@@ -346,7 +338,7 @@
 	 * @param	integer	the year
 	 * @return	array
 	 */
-	function adjust_date($month, $year)
+	public function adjust_date($month, $year)
 	{
 		$date = array();
 
@@ -365,7 +357,7 @@
 			$date['year']--;
 		}
 
-		if (strlen($date['month']) == 1)
+		if (strlen($date['month']) === 1)
 		{
 			$date['month'] = '0'.$date['month'];
 		}
@@ -383,7 +375,7 @@
 	 * @param	integer	the year
 	 * @return	integer
 	 */
-	function get_total_days($month, $year)
+	public function get_total_days($month, $year)
 	{
 		$days_in_month	= array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
 
@@ -414,7 +406,7 @@
 	 * @access	public
 	 * @return array
 	 */
-	function default_template()
+	public function default_template()
 	{
 		return  array (
 						'table_open'				=> '<table border="0" cellpadding="4" cellspacing="0">',
@@ -452,7 +444,7 @@
 	 * @access	public
 	 * @return	void
 	 */
-	function parse_template()
+	public function parse_template()
 	{
 		$this->temp = $this->default_template();
 
@@ -467,14 +459,11 @@
 		{
 			if (preg_match("/\{".$val."\}(.*?)\{\/".$val."\}/si", $this->template, $match))
 			{
-				$this->temp[$val] = $match['1'];
+				$this->temp[$val] = $match[1];
 			}
-			else
+			elseif (in_array($val, $today, TRUE))
 			{
-				if (in_array($val, $today, TRUE))
-				{
-					$this->temp[$val] = $this->temp[str_replace('_today', '', $val)];
-				}
+				$this->temp[$val] = $this->temp[substr($val, 0, -6)];
 			}
 		}
 	}
@@ -484,4 +473,4 @@
 // END CI_Calendar class
 
 /* End of file Calendar.php */
-/* Location: ./system/libraries/Calendar.php */
\ No newline at end of file
+/* Location: ./system/libraries/Calendar.php */
diff --git a/user_guide_src/source/changelog.rst b/user_guide_src/source/changelog.rst
index 8a7109f..4f060a4 100644
--- a/user_guide_src/source/changelog.rst
+++ b/user_guide_src/source/changelog.rst
@@ -41,6 +41,7 @@
       the SQL string of queries without executing them: get_compiled_select(),
       get_compiled_insert(), get_compiled_update(), get_compiled_delete().
    -  Taking care of LIKE condition when used with MySQL UPDATE statement.
+   -  Adding $escape parameter to the order_by function, this enables ordering by custom fields.
 
 -  Libraries
 
@@ -48,10 +49,11 @@
    -  CI_Loader::_ci_autoloader() is now a protected method.
    -  Modified valid_ip() to use PHP's filter_var() when possible (>= PHP 5.2) in the :doc:`Form Validation library <libraries/form_validation>`.
 	 -  Added custom filename to Email::attach() as $this->email->attach($filename, $disposition, $newname)
-   -  Cart library changes include;
+   -  Cart library changes include:
 	 -  It now auto-increments quantity's instead of just resetting it, this is the default behaviour of large e-commerce sites.
 	 -  Product Name strictness can be disabled via the Cart Library by switching "$product_name_safe"
 	 -  Added function remove() to remove a cart item, updating with quantity of 0 seemed like a hack but has remained to retain compatability
+   -  Minor speed optimizations and method & property visibility declarations in the Calendar Library.
 
 -  Core
 
@@ -67,15 +69,16 @@
    language file.
 -  Fixed a bug (#159, #163) that mishandled Active Record nested transactions because _trans_depth was not getting incremented.
 -  Fixed a bug (#737, #75) where pagination anchor class was not set properly when using initialize method.
--  Bug #419 - auto_link() now recognizes URLs that come after a word boundary.
--  Bug #724 - is_unique in form validation now checks that you are connected to a database.
--  Bug #647 - _get_mod_time() in Zip library no longer generates stat failed errors
--  Bug #608 - Fixes an issue with the Image_lib class not clearing properties completely
+-  Fixed a bug (#419) - auto_link() now recognizes URLs that come after a word boundary.
+-  Fixed a bug (#724) - is_unique in form validation now checks that you are connected to a database.
+-  Fixed a bug (#647) - _get_mod_time() in Zip library no longer generates stat failed errors
+-  Fixed a bug (#608) - Fixes an issue with the Image_lib class not clearing properties completely
 -  Fixed bugs (#157 and #174) - the Image_lib clear() function now resets all variables to their default values.
 -  Fixed a bug where using $this->dbforge->create_table() with PostgreSQL database could lead to fetching whole table.
--  Bug #795 - Fixed form method and accept-charset when passing an empty array.
--  Bug #797 - timespan was using incorrect seconds for year and month.
+-  Fixed a bug (#795) - Fixed form method and accept-charset when passing an empty array.
+-  Fixed a bug (#797) - timespan was using incorrect seconds for year and month.
 -  Fixed a bug in CI_Cart::contents() where if called without a TRUE (or equal) parameter, it would fail due to a typo.
+-  Fixed a bug (#696) - make oci_execute calls inside num_rows non-committing, since they are only there to reset which row is next in line for oci_fetch calls and thus don't need to be committed.
 
 Version 2.1.0
 =============
diff --git a/user_guide_src/source/libraries/migration.rst b/user_guide_src/source/libraries/migration.rst
new file mode 100644
index 0000000..5192f1f
--- /dev/null
+++ b/user_guide_src/source/libraries/migration.rst
@@ -0,0 +1,5 @@
+################
+Migrations Class
+################
+
+Coming soon.
\ No newline at end of file