Merge branch 'master' into bootstrapUI

This commit is contained in:
FrancescoUK
2016-03-13 16:19:44 +00:00
45 changed files with 477 additions and 289 deletions

View File

@@ -3,7 +3,7 @@ MAINTAINER jekkos
RUN sed -i -e 's/archive.ubuntu.com\|security.ubuntu.com/old-releases.ubuntu.com/g' /etc/apt/sources.list
RUN apt-get update
RUN apt-get -y upgrade
RUN DEBIAN_FRONTEND=noninteractive apt-get -y install mysql-client mysql-server apache2 libapache2-mod-php5 pwgen python-setuptools vim-tiny php5-mysql php5-gd nodejs npm curl
RUN DEBIAN_FRONTEND=noninteractive apt-get -y install mysql-client mysql-server apache2 libapache2-mod-php5 pwgen python-setuptools vim-tiny php5-mysql php5-gd php5-apcu nodejs npm curl
RUN easy_install supervisor
ADD ./docker/foreground.sh /etc/apache2/foreground.sh
ADD ./docker/supervisord.conf /etc/supervisord.conf

View File

@@ -25,6 +25,10 @@ username: admin
password:pointofsale
9. Enjoy
FAQ
---
If an blank page (HTTP status 500) shows after search completion or receipt generation, then double check php5-gd presence in your php installation. On windows check in php.ini whether the lib is installed. On Ubuntu issue `sudo apt-get install php5-gd`. Also have a look at the Dockerfile for a complete list of recommended packages.
13/01/2016: Install using Docker
-------------------------------
From now on ospos can be deployed using Docker on Linux, Mac or Windows. This setup dramatically reduces the number of possible issues as all setup is now done in a Dockerfile. Docker runs natively on mac and linux, but will require more overhead on windows. Please refer to the docker documentation for instructions on how to set it up on your platform.

View File

@@ -66,7 +66,7 @@ function get_sales_manage_sale_data_row($sale, $controller)
$controller_name = $CI->uri->segment(1);
$table_data_row='<tr>';
$table_data_row.='<td width="3%"><input type="checkbox" id="sale_' . $sale['sale_id'] . '" value="' . $sale['sale_id']. '" /></td>';
$table_data_row.='<td width="3%"><input class="print_hide" type="checkbox" id="sale_' . $sale['sale_id'] . '" value="' . $sale['sale_id']. '" /></td>';
$table_data_row.='<td width="15%">'.'POS ' . $sale['sale_id'] . '</td>';
$table_data_row.='<td width="17%">'.date( $CI->config->item('dateformat') . ' ' . $CI->config->item('timeformat'), strtotime($sale['sale_time']) ).'</td>';
$table_data_row.='<td width="23%">'.character_limiter( $sale['customer_name'], 25).'</td>';
@@ -75,12 +75,12 @@ function get_sales_manage_sale_data_row($sale, $controller)
$table_data_row.='<td width="8%">'.to_currency( $sale['change_due'] ).'</td>';
$table_data_row.='<td width="12%">'.$sale['payment_type'].'</td>';
$table_data_row.='<td width="8%">'.$sale['invoice_number'].'</td>';
$table_data_row.='<td width="8%">';
$table_data_row.=anchor($controller_name."/edit/" . $sale['sale_id'], $CI->lang->line('common_edit'),array('class'=>"modal-dlg modal-btn-delete modal-btn-submit",'title'=>$CI->lang->line($controller_name.'_update')));
$table_data_row.='<td width="8%" class="print_hide">';
$table_data_row.=anchor($controller_name."/edit/" . $sale['sale_id'], $CI->lang->line('common_edit'), array('class'=>'modal-dlg modal-btn-delete modal-btn print_hide', 'title'=>$CI->lang->line('common_edit')));
$table_data_row.='&nbsp;&nbsp;&nbsp;&nbsp;';
$table_data_row.='<a href="'.site_url($controller_name. "/receipt/" . $sale['sale_id']) . '">' . $CI->lang->line('sales_show_receipt') . '</a>';
$table_data_row.=anchor($controller_name."/receipt/" . $sale['sale_id'], $CI->lang->line('sales_show_receipt'), array('class'=>'print_hide', 'title'=>$CI->lang->line('sales_show_receipt')));
$table_data_row.='&nbsp;&nbsp;&nbsp;&nbsp;';
$table_data_row.='<a href="'.site_url($controller_name. "/invoice/" . $sale['sale_id']) . '">' . $CI->lang->line('sales_show_invoice') . '</a>';
$table_data_row.=anchor($controller_name."/invoice/" . $sale['sale_id'], $CI->lang->line('sales_show_invoice'), array('class'=>'print_hide', 'title'=>$CI->lang->line('sales_show_invoice')));
$table_data_row.='</td>';
$table_data_row.='</tr>';

View File

@@ -200,8 +200,8 @@ class Receiving_lib
'item_location'=>$item_location,
'stock_name'=>$this->CI->Stock_location->get_location_name($item_location),
'line'=>$insertkey,
'name'=>base64_encode($item_info->name),
'description'=>base64_encode($description!=null ? $description: $item_info->description),
'name'=>$item_info->name,
'description'=>$description!=null ? $description: $item_info->description,
'serialnumber'=>$serialnumber!=null ? $serialnumber: '',
'allow_alt_description'=>$item_info->allow_alt_description,
'is_serialized'=>$item_info->is_serialized,
@@ -236,7 +236,7 @@ class Receiving_lib
if(isset($items[$line]))
{
$line = &$items[$line];
$line['description'] = base64_encode($description);
$line['description'] = $description;
$line['serialnumber'] = $serialnumber;
$line['quantity'] = $quantity;
$line['discount'] = $discount;

View File

@@ -305,9 +305,9 @@ class Sale_lib
'item_location'=>$item_location,
'stock_name'=>$this->CI->Stock_location->get_location_name($item_location),
'line'=>$insertkey,
'name'=>base64_encode($item_info->name),
'name'=>$item_info->name,
'item_number'=>$item_info->item_number,
'description'=>base64_encode($description!=null ? $description: $item_info->description),
'description'=>$description!=null ? $description: $item_info->description,
'serialnumber'=>$serialnumber!=null ? $serialnumber: '',
'allow_alt_description'=>$item_info->allow_alt_description,
'is_serialized'=>$item_info->is_serialized,
@@ -396,7 +396,7 @@ class Sale_lib
if(isset($items[$line]))
{
$line = &$items[$line];
$line['description'] = base64_encode($description);
$line['description'] = $description;
$line['serialnumber'] = $serialnumber;
$line['quantity'] = $quantity;
$line['discount'] = $discount;

View File

@@ -76,12 +76,11 @@ class Receiving extends CI_Model
$cur_item_info = $this->Item->get_info($item['item_id']);
$receivings_items_data = array
(
$receivings_items_data = array(
'receiving_id'=>$receiving_id,
'item_id'=>$item['item_id'],
'line'=>$item['line'],
'description'=>base64_decode($item['description']),
'description'=>$item['description'],
'serialnumber'=>$item['serialnumber'],
'quantity_purchased'=>$item['quantity'],
'receiving_quantity'=>$item['receiving_quantity'],

View File

@@ -296,7 +296,7 @@ class Sale extends CI_Model
'sale_id'=>$sale_id,
'item_id'=>$item['item_id'],
'line'=>$item['line'],
'description'=>character_limiter(base64_decode($item['description']), 30),
'description'=>character_limiter($item['description'], 30),
'serialnumber'=>character_limiter($item['serialnumber'], 30),
'quantity_purchased'=>$item['quantity'],
'discount_percent'=>$item['discount'],

View File

@@ -86,7 +86,7 @@ class Sale_suspended extends CI_Model
'sale_id'=>$sale_id,
'item_id'=>$item['item_id'],
'line'=>$item['line'],
'description'=>character_limiter(base64_decode($item['description']), 30),
'description'=>character_limiter($item['description'], 30),
'serialnumber'=>character_limiter($item['serialnumber'], 30),
'quantity_purchased'=>$item['quantity'],
'discount_percent'=>$item['discount'],

View File

@@ -64,11 +64,11 @@
<!-- start mincss template tags -->
<link rel="stylesheet" type="text/css" href="dist/bootstrap.min.css?rel=9ed20b1ee8"/>
<link rel="stylesheet" type="text/css" href="dist/jquery-ui.css"/>
<link rel="stylesheet" type="text/css" href="dist/opensourcepos.min.css?rel=3ded88f8ce"/>
<link rel="stylesheet" type="text/css" href="dist/opensourcepos.min.css?rel=60674239d1"/>
<link rel="stylesheet" type="text/css" href="dist/opensourcepos_bower.css"/>
<!-- end mincss template tags -->
<!-- start minjs template tags -->
<script type="text/javascript" src="dist/opensourcepos.min.js?rel=52d78ada05" language="javascript"></script>
<script type="text/javascript" src="dist/opensourcepos.min.js?rel=10400d243b" language="javascript"></script>
<!-- end minjs template tags -->
<?php endif; ?>

View File

@@ -63,7 +63,7 @@ if (isset($error_message))
{
?>
<tr>
<td><span class='long_name'><?php echo base64_decode($item['name']); ?></span><span class='short_name'><?php echo character_limiter(base64_decode($item['name']),10); ?></span></td>
<td><span class='long_name'><?php echo $item['name']; ?></span><span class='short_name'><?php echo character_limiter($item['name'],10); ?></span></td>
<td><?php echo to_currency($item['price']); ?></td>
<td><?php echo $item['quantity'] . " " . ($show_stock_locations ? " [" . $item['stock_name'] . "]" : "");
?>&nbsp;&nbsp;&nbsp;x <?php echo $item['receiving_quantity'] != 0 ? $item['receiving_quantity'] : 1; ?></td>

View File

@@ -120,7 +120,7 @@ if (isset($error))
<?php echo form_open("receivings/edit_item/$line", array('class'=>'form-horizontal')); ?>
<tr>
<td><?php echo anchor("receivings/delete_item/$line", '<span class="glyphicon glyphicon-trash"></span>');?></td>
<td style="align: center;"><?php echo base64_decode($item['name']); ?><br /> [<?php echo $item['in_stock']; ?> in <?php echo $item['stock_name']; ?>]
<td style="align:center;"><?php echo $item['name']; ?><br /> [<?php echo $item['in_stock']; ?> in <?php echo $item['stock_name']; ?>]
<?php echo form_hidden('location', $item['item_location']); ?></td>
<?php
@@ -186,14 +186,14 @@ if (isset($error))
<?php
if($item['allow_alt_description']==1)
{
echo form_input(array('name'=>'description', 'class'=>'form-control input-sm', 'value'=>base64_decode($item['description'])));
echo form_input(array('name'=>'description', 'class'=>'form-control input-sm', 'value'=>$item['description']));
}
else
{
if (base64_decode($item['description'])!='')
if ($item['description']!='')
{
echo base64_decode($item['description']);
echo form_hidden('description',base64_decode($item['description']));
echo $item['description'];
echo form_hidden('description',$item['description']);
}
else
{

View File

@@ -75,7 +75,7 @@ if (isset($error_message))
?>
<tr class="item-row">
<td><?php echo $item['item_number']; ?></td>
<td class="item-name"><textarea rows="5" cols="6" class='long_name'><?php echo $item['is_serialized'] || $item['allow_alt_description'] && !empty($item['description']) ? base64_decode($item['description']) : base64_decode($item['name']); ?></textarea></td>
<td class="item-name"><textarea rows="5" cols="6" class='long_name'><?php echo $item['is_serialized'] || $item['allow_alt_description'] && !empty($item['description']) ? $item['description'] : $item['name']; ?></textarea></td>
<td style='text-align:center;'><textarea rows="5" cols="6"><?php echo $item['quantity']; ?></textarea></td>
<td><textarea rows="5" cols="6"><?php echo to_currency($item['price']); ?></textarea></td>
<td style='text-align:center;'><textarea rows="5" cols="6"><?php echo $item['discount'] .'%'; ?></textarea></td>

View File

@@ -197,12 +197,12 @@ function init_table_sorting()
<div id="title_bar">
<div id="title" class="float_left"><?php echo $this->lang->line('common_list_of').' '.$this->lang->line('sales_receipt_number'); ?></div>
<a href="javascript:window.print()"><div class="btn btn-info btn-sm pull-right"><span><?php echo $this->lang->line('common_print'); ?></span></div></a>
<a href="javascript:window.print()"><div class="btn btn-info btn-sm pull-right print_hide"><span><?php echo $this->lang->line('common_print'); ?></span></div></a>
</div>
<div id="pagination"><?= $links ?></div>
<div id="titleTextImg">
<div class="print_hide" id="titleTextImg">
<div style="float:left;vertical-align:text-top;"><?php echo $this->lang->line('common_search_options'). ': '; ?></div>
<a id="imageDivLink" href="javascript:show_hide_search_filter('search_filter_section', 'imageDivLink');" style="outline:none;">
<img src="<?php echo base_url().'images/plus.png'; ?>" style="border:0;outline:none;padding:0px;margin:0px;position:relative;top:-5px;"></a>
@@ -210,7 +210,7 @@ function init_table_sorting()
<?php echo form_open("$controller_name/search", array('id'=>'search_form', 'class'=>'form-horizontal')); ?>
<fieldset>
<div id="search_filter_section" class="form-group" style="display:none;">
<div id="search_filter_section" class="form-group print_show" style="display:none;">
<?php echo form_label($this->lang->line('sales_invoice_filter').' '.':', 'invoices_filter');?>
<?php echo form_checkbox(array('name'=>'only_invoices','id'=>'only_invoices','value'=>1,'checked'=> isset($only_invoices)? ( ($only_invoices)? 1 : 0) : 0)) . ' | ';?>
<?php echo form_label($this->lang->line('sales_cash_filter').' '.':', 'cash_filter');?>
@@ -222,7 +222,7 @@ function init_table_sorting()
<?php echo form_input(array('name'=>'end_date', 'value'=>$end_date, 'class'=>'date_filter', 'size' => '22'));?>
</div>
<div id="table_action_header" class="form-group">
<div id="table_action_header" class="form-group print_hide">
<ul>
<li class="float_left"><?php echo anchor($controller_name . "/delete", '<div class="btn btn-default btn-sm"><span>' . $this->lang->line("common_delete") . '</span></div>', array('id'=>'delete')); ?></li>
<!-- li class="float_left"><?php echo anchor($controller_name . "/update_invoice_numbers", '<div class="btn btn-default btn-sm"><span>' . $this->lang->line('sales_invoice_update') . '</span></div>', array('id'=>'update_invoice_numbers')); ?></li -->

View File

@@ -61,7 +61,7 @@ if (isset($error_message))
{
?>
<tr>
<td><span class='long_name'> <?php echo ucfirst(base64_decode($item['name'])); ?></span></td>
<td><span class='long_name'> <?php echo ucfirst($item['name']); ?></span></td>
<td><?php echo to_currency($item['price']); ?></td>
@@ -71,7 +71,7 @@ if (isset($error_message))
<td><div class="total-value"><?php echo to_currency($item[($this->Appconfig->get('show_total_discount') ? 'total' : 'discounted_total')]); ?></div></td>
</tr>
<tr>
<td colspan="2"><?php echo base64_decode($item['description']); ?></td>
<td colspan="2"><?php echo $item['description']; ?></td>
<td ><?php echo $item['serialnumber']; ?></td>
</tr>
<?php if ($item['discount'] > 0) : ?>

View File

@@ -127,7 +127,7 @@ if (isset($success))
<tr>
<td><?php echo anchor("sales/delete_item/$line", '<span class="glyphicon glyphicon-trash"></span>');?></td>
<td><?php echo $item['item_number']; ?></td>
<td style="align: center;"><?php echo base64_decode($item['name']); ?><br /> [<?php echo $item['in_stock'] ?> in <?php echo $item['stock_name']; ?>]
<td style="align: center;"><?php echo $item['name']; ?><br /> [<?php echo $item['in_stock'] ?> in <?php echo $item['stock_name']; ?>]
<?php echo form_hidden('location', $item['item_location']); ?>
</td>
@@ -179,14 +179,14 @@ if (isset($success))
<?php
if($item['allow_alt_description']==1)
{
echo form_input(array('name'=>'description', 'class'=>'form-control input-sm', 'value'=>base64_decode($item['description'])));
echo form_input(array('name'=>'description', 'class'=>'form-control input-sm', 'value'=>$item['description']));
}
else
{
if (base64_decode($item['description'])!='')
if ($item['description']!='')
{
echo base64_decode($item['description']);
echo form_hidden('description', base64_decode($item['description']));
echo $item['description'];
echo form_hidden('description', $item['description']);
}
else
{

View File

@@ -65,4 +65,13 @@
/*display:none;*/
}
}
.print_show
{
display:block !important;
}
.print_hide
{
display:none !important;
}
}

View File

File diff suppressed because one or more lines are too long

View File

File diff suppressed because one or more lines are too long

View File

@@ -55,7 +55,7 @@ defined('BASEPATH') OR exit('No direct script access allowed');
* @var string
*
*/
define('CI_VERSION', '3.0.4');
define('CI_VERSION', '3.0.5');
/*
* ------------------------------------------------------
@@ -359,7 +359,7 @@ if ( ! is_php('5.4'))
*
* Returns current CI instance object
*
* @return object
* @return CI_Controller
*/
function &get_instance()
{

View File

@@ -321,7 +321,7 @@ class CI_Loader {
}
$model = ucfirst($model);
if ( ! class_exists($model))
if ( ! class_exists($model, FALSE))
{
foreach ($this->_ci_model_paths as $mod_path)
{
@@ -718,9 +718,16 @@ class CI_Loader {
{
if (is_array($library))
{
foreach ($library as $driver)
foreach ($library as $key => $value)
{
$this->driver($driver);
if (is_int($key))
{
$this->driver($value, $params);
}
else
{
$this->driver($key, $params, $value);
}
}
return $this;
@@ -929,6 +936,14 @@ class CI_Loader {
*/
if (is_array($_ci_vars))
{
foreach (array_keys($_ci_vars) as $key)
{
if (strncmp($key, '_ci_', 4) === 0)
{
unset($_ci_vars[$key]);
}
}
$this->_ci_cached_vars = array_merge($this->_ci_cached_vars, $_ci_vars);
}
extract($this->_ci_cached_vars);
@@ -1334,10 +1349,7 @@ class CI_Loader {
// Autoload drivers
if (isset($autoload['drivers']))
{
foreach ($autoload['drivers'] as $item)
{
$this->driver($item);
}
$this->driver($autoload['drivers']);
}
// Load libraries

View File

@@ -154,8 +154,8 @@ class CI_Log {
*
* Generally this function will be called using the global log_message() function
*
* @param string the error level: 'error', 'debug' or 'info'
* @param string the error message
* @param string $level The error level: 'error', 'debug' or 'info'
* @param string $msg The error message
* @return bool
*/
public function write_log($level, $msg)
@@ -191,6 +191,8 @@ class CI_Log {
return FALSE;
}
flock($fp, LOCK_EX);
// Instantiating DateTime with microseconds appended to initial date is needed for proper support of this format
if (strpos($this->_date_fmt, 'u') !== FALSE)
{
@@ -204,9 +206,7 @@ class CI_Log {
$date = date($this->_date_fmt);
}
$message .= $level.' - '.$date.' --> '.$msg."\n";
flock($fp, LOCK_EX);
$message .= $this->_format_line($level, $date, $msg);
for ($written = 0, $length = strlen($message); $written < $length; $written += $result)
{
@@ -227,4 +227,21 @@ class CI_Log {
return is_int($result);
}
// --------------------------------------------------------------------
/**
* Format the log line.
*
* This is for extensibility of log formatting
* If you want to change the log format, extend the CI_Log class and override this method
*
* @param string $level The error level
* @param string $date Formatted date string
* @param string $msg The log message
* @return string Formatted log line with a new line character '\n' at the end
*/
protected function _format_line($level, $date, $message)
{
return $level.' - '.$date.' --> '.$message."\n";
}
}

View File

@@ -377,7 +377,7 @@ class CI_Output {
/**
* Set Cache
*
* @param int $time Cache expiration time in seconds
* @param int $time Cache expiration time in minutes
* @return CI_Output
*/
public function cache($time)

View File

@@ -762,7 +762,14 @@ class CI_Security {
*/
public function strip_image_tags($str)
{
return preg_replace(array('#<img[\s/]+.*?src\s*=\s*["\'](.+?)["\'].*?\>#', '#<img[\s/]+.*?src\s*=\s*(.+?).*?\>#'), '\\1', $str);
return preg_replace(
array(
'#<img[\s/]+.*?src\s*=\s*(["\'])([^\\1]+?)\\1.*?\>#i',
'#<img[\s/]+.*?src\s*=\s*?(([^\s"\'=<>`]+)).*?\>#i'
),
'\\2',
$str
);
}
// ----------------------------------------------------------------

View File

@@ -1566,11 +1566,11 @@ abstract class CI_DB_driver {
'\s*>\s*', // >
'\s+IS NULL', // IS NULL
'\s+IS NOT NULL', // IS NOT NULL
'\s+EXISTS\s*\([^\)]+\)', // EXISTS(sql)
'\s+NOT EXISTS\s*\([^\)]+\)', // NOT EXISTS(sql)
'\s+EXISTS\s*\(.*\)', // EXISTS(sql)
'\s+NOT EXISTS\s*\(.*\)', // NOT EXISTS(sql)
'\s+BETWEEN\s+', // BETWEEN value AND value
'\s+IN\s*\([^\)]+\)', // IN(list)
'\s+NOT IN\s*\([^\)]+\)', // NOT IN (list)
'\s+IN\s*\(.*\)', // IN(list)
'\s+NOT IN\s*\(.*\)', // NOT IN (list)
'\s+LIKE\s+\S.*('.$_les.')?', // LIKE 'expr'[ ESCAPE '%s']
'\s+NOT LIKE\s+\S.*('.$_les.')?' // NOT LIKE 'expr'[ ESCAPE '%s']
);
@@ -1793,7 +1793,7 @@ abstract class CI_DB_driver {
* the table prefix onto it. Some logic is necessary in order to deal with
* column names that include the path. Consider a query like this:
*
* SELECT * FROM hostname.database.table.column AS c FROM hostname.database.table
* SELECT hostname.database.table.column AS c FROM hostname.database.table
*
* Or a query with aliasing:
*

View File

@@ -531,40 +531,47 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
is_bool($escape) OR $escape = $this->_protect_identifiers;
// Split multiple conditions
if ($escape === TRUE && preg_match_all('/\sAND\s|\sOR\s/i', $cond, $m, PREG_OFFSET_CAPTURE))
{
$newcond = '';
$m[0][] = array('', strlen($cond));
for ($i = 0, $c = count($m[0]), $s = 0;
$i < $c;
$s = $m[0][$i][1] + strlen($m[0][$i][0]), $i++)
{
$temp = substr($cond, $s, ($m[0][$i][1] - $s));
$newcond .= preg_match("/([\[\]\w\.'-]+)(\s*[^\"\[`'\w]+\s*)(.+)/i", $temp, $match)
? $this->protect_identifiers($match[1]).$match[2].$this->protect_identifiers($match[3])
: $temp;
$newcond .= $m[0][$i][0];
}
$cond = ' ON '.$newcond;
}
// Split apart the condition and protect the identifiers
elseif ($escape === TRUE && preg_match("/([\[\]\w\.'-]+)(\s*[^\"\[`'\w]+\s*)(.+)/i", $cond, $match))
{
$cond = ' ON '.$this->protect_identifiers($match[1]).$match[2].$this->protect_identifiers($match[3]);
}
elseif ( ! $this->_has_operator($cond))
if ( ! $this->_has_operator($cond))
{
$cond = ' USING ('.($escape ? $this->escape_identifiers($cond) : $cond).')';
}
else
elseif ($escape === FALSE)
{
$cond = ' ON '.$cond;
}
else
{
// Split multiple conditions
if (preg_match_all('/\sAND\s|\sOR\s/i', $cond, $joints, PREG_OFFSET_CAPTURE))
{
$conditions = array();
$joints = $joints[0];
array_unshift($joints, array('', 0));
for ($i = count($joints) - 1, $pos = strlen($cond); $i >= 0; $i--)
{
$joints[$i][1] += strlen($joints[$i][0]); // offset
$conditions[$i] = substr($cond, $joints[$i][1], $pos - $joints[$i][1]);
$pos = $joints[$i][1] - strlen($joints[$i][0]);
$joints[$i] = $joints[$i][0];
}
}
else
{
$conditions = array($cond);
$joints = array('');
}
$cond = ' ON ';
for ($i = 0, $c = count($conditions); $i < $c; $i++)
{
$operator = $this->_get_operator($conditions[$i]);
$cond .= $joints[$i];
$cond .= preg_match("/(\(*)?([\[\]\w\.'-]+)".preg_quote($operator)."(.*)/i", $conditions[$i], $match)
? $match[1].$this->protect_identifiers($match[2]).$operator.$this->protect_identifiers($match[3])
: $conditions[$i];
}
}
// Do we want to escape the table name?
if ($escape === TRUE)
@@ -1138,7 +1145,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
* @param string $key
* @param string $value
* @param bool $escape
* @return object
* @return CI_DB_query_builder
*/
public function having($key, $value = NULL, $escape = NULL)
{
@@ -1155,7 +1162,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
* @param string $key
* @param string $value
* @param bool $escape
* @return object
* @return CI_DB_query_builder
*/
public function or_having($key, $value = NULL, $escape = NULL)
{
@@ -1339,7 +1346,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
* @param string the table
* @param string the limit clause
* @param string the offset clause
* @return object
* @return CI_DB_result
*/
public function get($table = '', $limit = NULL, $offset = NULL)
{
@@ -1379,7 +1386,16 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
$this->from($table);
}
$result = ($this->qb_distinct === TRUE OR ! empty($this->qb_orderby))
// ORDER BY usage is often problematic here (most notably
// on Microsoft SQL Server) and ultimately unnecessary
// for selecting COUNT(*) ...
if ( ! empty($this->qb_orderby))
{
$orderby = $this->qb_orderby;
$this->qb_orderby = NULL;
}
$result = ($this->qb_distinct === TRUE)
? $this->query($this->_count_string.$this->protect_identifiers('numrows')."\nFROM (\n".$this->_compile_select()."\n) CI_count_all_results")
: $this->query($this->_compile_select($this->_count_string.$this->protect_identifiers('numrows')));
@@ -1387,6 +1403,11 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
{
$this->_reset_select();
}
// If we've previously reset the qb_orderby values, get them back
elseif ( ! isset($this->qb_orderby))
{
$this->qb_orderby = $orderby;
}
if ($result->num_rows() === 0)
{
@@ -1408,7 +1429,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
* @param string $where
* @param int $limit
* @param int $offset
* @return object
* @return CI_DB_result
*/
public function get_where($table = '', $where = NULL, $limit = NULL, $offset = NULL)
{
@@ -1444,20 +1465,26 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
* @param bool $escape Whether to escape values and identifiers
* @return int Number of rows inserted or FALSE on failure
*/
public function insert_batch($table = '', $set = NULL, $escape = NULL)
public function insert_batch($table, $set = NULL, $escape = NULL, $batch_size = 100)
{
if ($set !== NULL)
if ($set === NULL)
{
if (empty($this->qb_set))
{
return ($this->db_debug) ? $this->display_error('db_must_use_set') : FALSE;
}
}
else
{
if (empty($set))
{
return ($this->db_debug) ? $this->display_error('insert_batch() called with no data') : FALSE;
}
$this->set_insert_batch($set, '', $escape);
}
if (count($this->qb_set) === 0)
{
// No valid data array. Folds in cases where keys and values did not match up
return ($this->db_debug) ? $this->display_error('db_must_use_set') : FALSE;
}
if ($table === '')
if (strlen($table) === 0)
{
if ( ! isset($this->qb_from[0]))
{
@@ -1469,9 +1496,9 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
// Batch this baby
$affected_rows = 0;
for ($i = 0, $total = count($this->qb_set); $i < $total; $i += 100)
for ($i = 0, $total = count($this->qb_set); $i < $total; $i += $batch_size)
{
$this->query($this->_insert_batch($this->protect_identifiers($table, TRUE, $escape, FALSE), $this->qb_keys, array_slice($this->qb_set, $i, 100)));
$this->query($this->_insert_batch($this->protect_identifiers($table, TRUE, $escape, FALSE), $this->qb_keys, array_slice($this->qb_set, $i, $batch_size)));
$affected_rows += $this->affected_rows();
}
@@ -1598,7 +1625,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
* @param string the table to insert data into
* @param array an associative array of insert values
* @param bool $escape Whether to escape values and identifiers
* @return object
* @return bool TRUE on success, FALSE on failure
*/
public function insert($table = '', $set = NULL, $escape = NULL)
{
@@ -1664,7 +1691,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
*
* @param string the table to replace data into
* @param array an associative array of insert values
* @return object
* @return bool TRUE on success, FALSE on failure
*/
public function replace($table = '', $set = NULL)
{
@@ -1770,7 +1797,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
* @param array $set An associative array of update values
* @param mixed $where
* @param int $limit
* @return object
* @return bool TRUE on success, FALSE on failure
*/
public function update($table = '', $set = NULL, $where = NULL, $limit = NULL)
{
@@ -1845,7 +1872,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
* @param string the where key
* @return int number of rows affected or FALSE on failure
*/
public function update_batch($table = '', $set = NULL, $index = NULL)
public function update_batch($table, $set = NULL, $index = NULL, $batch_size = 100)
{
// Combine any cached components with the current statements
$this->_merge_cache();
@@ -1855,17 +1882,24 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
return ($this->db_debug) ? $this->display_error('db_must_use_index') : FALSE;
}
if ($set !== NULL)
if ($set === NULL)
{
if (empty($this->qb_set))
{
return ($this->db_debug) ? $this->display_error('db_must_use_set') : FALSE;
}
}
else
{
if (empty($set))
{
return ($this->db_debug) ? $this->display_error('update_batch() called with no data') : FALSE;
}
$this->set_update_batch($set, $index);
}
if (count($this->qb_set) === 0)
{
return ($this->db_debug) ? $this->display_error('db_must_use_set') : FALSE;
}
if ($table === '')
if (strlen($table) === 0)
{
if ( ! isset($this->qb_from[0]))
{
@@ -1877,9 +1911,9 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
// Batch this baby
$affected_rows = 0;
for ($i = 0, $total = count($this->qb_set); $i < $total; $i += 100)
for ($i = 0, $total = count($this->qb_set); $i < $total; $i += $batch_size)
{
$this->query($this->_update_batch($this->protect_identifiers($table, TRUE, NULL, FALSE), array_slice($this->qb_set, $i, 100), $this->protect_identifiers($index)));
$this->query($this->_update_batch($this->protect_identifiers($table, TRUE, NULL, FALSE), array_slice($this->qb_set, $i, $batch_size), $this->protect_identifiers($index)));
$affected_rows += $this->affected_rows();
$this->qb_where = array();
}
@@ -1983,7 +2017,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
* Compiles a delete string and runs "DELETE FROM table"
*
* @param string the table to empty
* @return object
* @return bool TRUE on success, FALSE on failure
*/
public function empty_table($table = '')
{
@@ -2016,7 +2050,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
* This function maps to "DELETE FROM table"
*
* @param string the table to truncate
* @return object
* @return bool TRUE on success, FALSE on failure
*/
public function truncate($table = '')
{
@@ -2316,7 +2350,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
*
* Escapes identifiers in WHERE and HAVING statements at execution time.
*
* Required so that aliases are tracked properly, regardless of wether
* Required so that aliases are tracked properly, regardless of whether
* where(), or_where(), having(), or_having are called prior to from(),
* join() and dbprefix is added only if needed.
*

View File

@@ -126,7 +126,7 @@ class CI_DB_ibase_driver extends CI_DB {
*/
protected function _execute($sql)
{
return ibase_query($this->conn_id, $sql);
return ibase_query(isset($this->_ibase_trans) ? $this->_ibase_trans : $this->conn_id, $sql);
}
// --------------------------------------------------------------------

View File

@@ -171,35 +171,36 @@ if ( ! function_exists('create_captcha'))
$byte_index = $word_index = 0;
while ($word_index < $word_length)
{
// Do we have more random data to use?
// It could be exhausted by previous iterations
// ignoring bytes higher than $rand_max.
if ($byte_index === $pool_length)
{
// No failures should be possible if the
// first get_random_bytes() call didn't
// return FALSE, but still ...
for ($i = 0; $i < 5; $i++)
{
if (($bytes = $security->get_random_bytes($pool_length)) === FALSE)
{
continue;
}
$byte_index = 0;
break;
}
if ($bytes === FALSE)
{
// Sadly, this means fallback to mt_rand()
$word = '';
break;
}
}
list(, $rand_index) = unpack('C', $bytes[$byte_index++]);
if ($rand_index > $rand_max)
{
// Was this the last byte we have?
// If so, try to fetch more.
if ($byte_index === $pool_length)
{
// No failures should be possible if
// the first get_random_bytes() call
// didn't return FALSE, but still ...
for ($i = 0; $i < 5; $i++)
{
if (($bytes = $security->get_random_bytes($pool_length)) === FALSE)
{
continue;
}
$byte_index = 0;
break;
}
if ($bytes === FALSE)
{
// Sadly, this means fallback to mt_rand()
$word = '';
break;
}
}
continue;
}

View File

@@ -791,7 +791,7 @@ if ( ! function_exists('set_checkbox'))
// Unchecked checkbox and radio inputs are not even submitted by browsers ...
if ($CI->input->method() === 'post')
{
return ($input === 'value') ? ' checked="checked"' : '';
return ($input === $value) ? ' checked="checked"' : '';
}
return ($default === TRUE) ? ' checked="checked"' : '';
@@ -843,7 +843,7 @@ if ( ! function_exists('set_radio'))
// Unchecked checkbox and radio inputs are not even submitted by browsers ...
if ($CI->input->method() === 'post')
{
return ($input === 'value') ? ' checked="checked"' : '';
return ($input === $value) ? ' checked="checked"' : '';
}
return ($default === TRUE) ? ' checked="checked"' : '';

View File

@@ -219,7 +219,7 @@ if ( ! function_exists('humanize'))
*/
function humanize($str, $separator = '_')
{
return ucwords(preg_replace('/['.$separator.']+/', ' ', trim(MB_ENABLED ? mb_strtolower($str) : strtolower($str))));
return ucwords(preg_replace('/['.preg_quote($separator).']+/', ' ', trim(MB_ENABLED ? mb_strtolower($str) : strtolower($str))));
}
}

View File

@@ -275,13 +275,28 @@ if ( ! function_exists('word_censor'))
foreach ($censored as $badword)
{
$badword = str_replace('\*', '\w*?', preg_quote($badword, '/'));
if ($replacement !== '')
{
$str = preg_replace("/({$delim})(".str_replace('\*', '\w*?', preg_quote($badword, '/')).")({$delim})/i", "\\1{$replacement}\\3", $str);
$str = preg_replace(
"/({$delim})(".$badword.")({$delim})/i",
"\\1{$replacement}\\3",
$str
);
}
else
elseif (preg_match_all("/{$delim}(".$badword."){$delim}/i", $str, $matches, PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE))
{
$str = preg_replace("/({$delim})(".str_replace('\*', '\w*?', preg_quote($badword, '/')).")({$delim})/ie", "'\\1'.str_repeat('#', strlen('\\2')).'\\3'", $str);
$matches = $matches[1];
for ($i = count($matches) - 1; $i >= 0; $i--)
{
$length = strlen($matches[$i][0]);
$str = substr_replace(
$str,
str_repeat('#', $length),
$matches[$i][1],
$length
);
}
}
}

View File

@@ -48,6 +48,24 @@ defined('BASEPATH') OR exit('No direct script access allowed');
*/
class CI_Cache_apc extends CI_Driver {
/**
* Class constructor
*
* Only present so that an error message is logged
* if APC is not available.
*
* @return void
*/
public function __construct()
{
if ( ! $this->is_supported())
{
log_message('error', 'Cache: Failed to initialize APC; extension not loaded/enabled?');
}
}
// ------------------------------------------------------------------------
/**
* Get
*
@@ -198,13 +216,6 @@ class CI_Cache_apc extends CI_Driver {
*/
public function is_supported()
{
if ( ! extension_loaded('apc') OR ! ini_get('apc.enabled'))
{
log_message('debug', 'The APC PHP extension must be loaded to use APC Cache.');
return FALSE;
}
return TRUE;
return (extension_loaded('apc') && ini_get('apc.enabled'));
}
}

View File

@@ -107,6 +107,7 @@ class CI_Cache_memcached extends CI_Driver {
else
{
log_message('error', 'Cache: Failed to create Memcache(d) object; extension not loaded?');
return;
}
foreach ($this->_memcache_conf as $cache_server)

View File

@@ -91,6 +91,12 @@ class CI_Cache_redis extends CI_Driver
*/
public function __construct()
{
if ( ! $this->is_supported())
{
log_message('error', 'Cache: Failed to create Redis object; extension not loaded?');
return;
}
$config = array();
$CI =& get_instance();

View File

@@ -51,6 +51,24 @@ defined('BASEPATH') OR exit('No direct script access allowed');
*/
class CI_Cache_wincache extends CI_Driver {
/**
* Class constructor
*
* Only present so that an error message is logged
* if APC is not available.
*
* @return void
*/
public function __construct()
{
if ( ! $this->is_supported())
{
log_message('error', 'Cache: Failed to initialize Wincache; extension not loaded/enabled?');
}
}
// ------------------------------------------------------------------------
/**
* Get
*
@@ -194,13 +212,6 @@ class CI_Cache_wincache extends CI_Driver {
*/
public function is_supported()
{
if ( ! extension_loaded('wincache') OR ! ini_get('wincache.ucenabled'))
{
log_message('debug', 'The Wincache PHP extension must be loaded to use Wincache Cache.');
return FALSE;
}
return TRUE;
return (extension_loaded('wincache') && ini_get('wincache.ucenabled'));
}
}

View File

@@ -574,14 +574,18 @@ class CI_Email {
$this->validate_email($this->_str_to_array($replyto));
}
if ($name === '')
if ($name !== '')
{
$name = $replyto;
}
if (strpos($name, '"') !== 0)
{
$name = '"'.$name.'"';
// only use Q encoding if there are characters that would require it
if ( ! preg_match('/[\200-\377]/', $name))
{
// add slashes for non-printing characters, slashes, and double quotes, and surround it in double quotes
$name = '"'.addcslashes($name, "\0..\37\177'\"\\").'"';
}
else
{
$name = $this->_prep_q_encoding($name);
}
}
$this->set_header('Reply-To', $name.' <'.$replyto.'>');

View File

@@ -637,21 +637,7 @@ class CI_Form_validation {
// Set the message type
$type = in_array('required', $rules) ? 'required' : 'isset';
// Check if a custom message is defined
if (isset($this->_field_data[$row['field']]['errors'][$type]))
{
$line = $this->_field_data[$row['field']]['errors'][$type];
}
elseif (isset($this->_error_messages[$type]))
{
$line = $this->_error_messages[$type];
}
elseif (FALSE === ($line = $this->CI->lang->line('form_validation_'.$type))
// DEPRECATED support for non-prefixed keys
&& FALSE === ($line = $this->CI->lang->line($type, FALSE)))
{
$line = 'The field was not set';
}
$line = $this->_get_error_message($type, $row['field']);
// Build the error message
$message = $this->_build_error_msg($line, $this->_translate_fieldname($row['label']));
@@ -820,23 +806,9 @@ class CI_Form_validation {
{
$line = $this->CI->lang->line('form_validation_error_message_not_set').'(Anonymous function)';
}
// Check if a custom message is defined
elseif (isset($this->_field_data[$row['field']]['errors'][$rule]))
{
$line = $this->_field_data[$row['field']]['errors'][$rule];
}
elseif ( ! isset($this->_error_messages[$rule]))
{
if (FALSE === ($line = $this->CI->lang->line('form_validation_'.$rule))
// DEPRECATED support for non-prefixed keys
&& FALSE === ($line = $this->CI->lang->line($rule, FALSE)))
{
$line = $this->CI->lang->line('form_validation_error_message_not_set').'('.$rule.')';
}
}
else
{
$line = $this->_error_messages[$rule];
$line = $this->_get_error_message($rule, $row['field']);
}
// Is the parameter we are inserting into the error message the name
@@ -864,6 +836,40 @@ class CI_Form_validation {
// --------------------------------------------------------------------
/**
* Get the error message for the rule
*
* @param string $rule The rule name
* @param string $field The field name
* @return string
*/
protected function _get_error_message($rule, $field)
{
// check if a custom message is defined through validation config row.
if (isset($this->_field_data[$field]['errors'][$rule]))
{
return $this->_field_data[$field]['errors'][$rule];
}
// check if a custom message has been set using the set_message() function
elseif (isset($this->_error_messages[$rule]))
{
return $this->_error_messages[$rule];
}
elseif (FALSE !== ($line = $this->CI->lang->line('form_validation_'.$rule)))
{
return $line;
}
// DEPRECATED support for non-prefixed keys, lang file again
elseif (FALSE !== ($line = $this->CI->lang->line($rule, FALSE)))
{
return $line;
}
return $this->CI->lang->line('form_validation_error_message_not_set').'('.$rule.')';
}
// --------------------------------------------------------------------
/**
* Translate a field name
*
@@ -1214,6 +1220,14 @@ class CI_Form_validation {
$str = $matches[2];
}
// PHP 7 accepts IPv6 addresses within square brackets as hostnames,
// but it appears that the PR that came in with https://bugs.php.net/bug.php?id=68039
// was never merged into a PHP 5 branch ... https://3v4l.org/8PsSN
if (preg_match('/^\[([^\]]+)\]/', $str, $matches) && ! is_php('7') && filter_var($matches[1], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) !== FALSE)
{
$str = 'ipv6.host'.substr($str, strlen($matches[1]) + 2);
}
$str = 'http://'.$str;
// There's a bug affecting PHP 5.2.13, 5.3.2 that considers the

View File

@@ -497,7 +497,7 @@ class CI_Pagination {
{
$this->cur_page = $this->CI->input->get($this->query_string_segment);
}
else if (!$this->cur_page)
elseif (empty($this->cur_page))
{
// Default to the last segment number if one hasn't been defined.
if ($this->uri_segment === 0)
@@ -512,16 +512,18 @@ class CI_Pagination {
{
$this->cur_page = str_replace(array($this->prefix, $this->suffix), '', $this->cur_page);
}
} else {
$this->cur_page = (string) $this->cur_page;
}
}
else
{
$this->cur_page = (string) $this->cur_page;
}
// If something isn't quite right, back to the default base page.
if ( ! ctype_digit($this->cur_page) OR ($this->use_page_numbers && (int) $this->cur_page === 0))
{
$this->cur_page = $base_page;
}
elseif (empty($this->cur_page))
else
{
// Make sure we're using integers for comparisons later.
$this->cur_page = (int) $this->cur_page;

View File

@@ -314,12 +314,14 @@ class CI_Profiler {
foreach ($_GET as $key => $val)
{
is_int($key) OR $key = "'".$key."'";
is_int($key) OR $key = "'".htmlspecialchars($key, ENT_QUOTES, config_item('charset'))."'";
$val = (is_array($val) OR is_object($val))
? '<pre>'.htmlspecialchars(print_r($val, TRUE), ENT_QUOTES, config_item('charset'))
: htmlspecialchars($val, ENT_QUOTES, config_item('charset'));
$output .= '<tr><td style="width:50%;color:#000;background-color:#ddd;padding:5px;">&#36;_GET['
.$key.']&nbsp;&nbsp; </td><td style="width:50%;padding:5px;color:#cd6e00;font-weight:normal;background-color:#ddd;">'
.((is_array($val) OR is_object($val)) ? '<pre>'.htmlspecialchars(stripslashes(print_r($val, TRUE))).'</pre>' : htmlspecialchars(stripslashes($val)))
."</td></tr>\n";
.$val."</td></tr>\n";
}
$output .= "</table>\n";
@@ -352,36 +354,26 @@ class CI_Profiler {
foreach ($_POST as $key => $val)
{
is_int($key) OR $key = "'".$key."'";
is_int($key) OR $key = "'".htmlspecialchars($key, ENT_QUOTES, config_item('charset'))."'";
$val = (is_array($val) OR is_object($val))
? '<pre>'.htmlspecialchars(print_r($val, TRUE), ENT_QUOTES, config_item('charset'))
: htmlspecialchars($val, ENT_QUOTES, config_item('charset'));
$output .= '<tr><td style="width:50%;padding:5px;color:#000;background-color:#ddd;">&#36;_POST['
.$key.']&nbsp;&nbsp; </td><td style="width:50%;padding:5px;color:#009900;font-weight:normal;background-color:#ddd;">';
if (is_array($val) OR is_object($val))
{
$output .= '<pre>'.htmlspecialchars(stripslashes(print_r($val, TRUE))).'</pre>';
}
else
{
$output .= htmlspecialchars(stripslashes($val));
}
$output .= "</td></tr>\n";
.$key.']&nbsp;&nbsp; </td><td style="width:50%;padding:5px;color:#009900;font-weight:normal;background-color:#ddd;">'
.$val."</td></tr>\n";
}
foreach ($_FILES as $key => $val)
{
is_int($key) OR $key = "'".$key."'";
is_int($key) OR $key = "'".htmlspecialchars($key, ENT_QUOTES, config_item('charset'))."'";
$val = (is_array($val) OR is_object($val))
? '<pre>'.htmlspecialchars(print_r($val, TRUE), ENT_QUOTES, config_item('charset'))
: htmlspecialchars($val, ENT_QUOTES, config_item('charset'));
$output .= '<tr><td style="width:50%;padding:5px;color:#000;background-color:#ddd;">&#36;_FILES['
.$key.']&nbsp;&nbsp; </td><td style="width:50%;padding:5px;color:#009900;font-weight:normal;background-color:#ddd;">';
if (is_array($val) OR is_object($val))
{
$output .= '<pre>'.htmlspecialchars(stripslashes(print_r($val, TRUE))).'</pre>';
}
$output .= "</td></tr>\n";
.$key.']&nbsp;&nbsp; </td><td style="width:50%;padding:5px;color:#009900;font-weight:normal;background-color:#ddd;">'
.$val."</td></tr>\n";
}
$output .= "</table>\n";
@@ -465,7 +457,7 @@ class CI_Profiler {
foreach (array('HTTP_ACCEPT', 'HTTP_USER_AGENT', 'HTTP_CONNECTION', 'SERVER_PORT', 'SERVER_NAME', 'REMOTE_ADDR', 'SERVER_SOFTWARE', 'HTTP_ACCEPT_LANGUAGE', 'SCRIPT_NAME', 'REQUEST_METHOD',' HTTP_HOST', 'REMOTE_HOST', 'CONTENT_TYPE', 'SERVER_PROTOCOL', 'QUERY_STRING', 'HTTP_ACCEPT_ENCODING', 'HTTP_X_FORWARDED_FOR', 'HTTP_DNT') as $header)
{
$val = isset($_SERVER[$header]) ? $_SERVER[$header] : '';
$val = isset($_SERVER[$header]) ? htmlspecialchars($_SERVER[$header], ENT_QUOTES, config_item('charset')) : '';
$output .= '<tr><td style="vertical-align:top;width:50%;padding:5px;color:#900;background-color:#ddd;">'
.$header.'&nbsp;&nbsp;</td><td style="width:50%;padding:5px;color:#000;background-color:#ddd;">'.$val."</td></tr>\n";
}

View File

@@ -231,7 +231,7 @@ class CI_Session {
}
}
if ( ! class_exists($prefix.$class) && file_exists($file_path = APPPATH.'libraries/Session/drivers/'.$prefix.$class.'.php'))
if ( ! class_exists($prefix.$class, FALSE) && file_exists($file_path = APPPATH.'libraries/Session/drivers/'.$prefix.$class.'.php'))
{
require_once($file_path);
if (class_exists($prefix.$class, FALSE))

View File

@@ -168,4 +168,24 @@ abstract class CI_Session_driver implements SessionHandlerInterface {
return TRUE;
}
// ------------------------------------------------------------------------
/**
* Fail
*
* Drivers other than the 'files' one don't (need to) use the
* session.save_path INI setting, but that leads to confusing
* error messages emitted by PHP when open() or write() fail,
* as the message contains session.save_path ...
* To work around the problem, the drivers will call this method
* so that the INI is set just in time for the error message to
* be properly generated.
*
* @return mixed
*/
protected function _fail()
{
ini_set('session.save_path', config_item('sess_save_path'));
return $this->_failure;
}
}

View File

@@ -127,7 +127,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan
{
if (empty($this->_db->conn_id) && ! $this->_db->db_connect())
{
return $this->_failure;
return $this->_fail();
}
return $this->_success;
@@ -163,7 +163,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan
$this->_db->where('ip_address', $_SERVER['REMOTE_ADDR']);
}
if (($result = $this->_db->get()->row()) === NULL)
if ( ! ($result = $this->_db->get()) OR ($result = $result->row()) === NULL)
{
// PHP7 will reuse the same SessionHandler object after
// ID regeneration, so we need to explicitly set this to
@@ -210,7 +210,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan
{
if ( ! $this->_release_lock() OR ! $this->_get_lock($session_id))
{
return $this->_failure;
return $this->_fail();
}
$this->_row_exists = FALSE;
@@ -218,7 +218,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan
}
elseif ($this->_lock === FALSE)
{
return $this->_failure;
return $this->_fail();
}
if ($this->_row_exists === FALSE)
@@ -237,7 +237,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan
return $this->_success;
}
return $this->_failure;
return $this->_fail();
}
$this->_db->where('id', $session_id);
@@ -260,7 +260,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan
return $this->_success;
}
return $this->_failure;
return $this->_fail();
}
// ------------------------------------------------------------------------
@@ -275,7 +275,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan
public function close()
{
return ($this->_lock && ! $this->_release_lock())
? $this->_failure
? $this->_fail()
: $this->_success;
}
@@ -304,7 +304,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan
if ( ! $this->_db->delete($this->_config['save_path']))
{
return $this->_failure;
return $this->_fail();
}
}
@@ -314,7 +314,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan
return $this->_success;
}
return $this->_failure;
return $this->_fail();
}
// ------------------------------------------------------------------------
@@ -334,7 +334,7 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan
return ($this->_db->delete($this->_config['save_path'], 'timestamp < '.(time() - $maxlifetime)))
? $this->_success
: $this->_failure;
: $this->_fail();
}
// ------------------------------------------------------------------------
@@ -414,5 +414,4 @@ class CI_Session_database_driver extends CI_Session_driver implements SessionHan
return parent::_release_lock();
}
}

View File

@@ -117,7 +117,7 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa
{
$this->_memcached = NULL;
log_message('error', 'Session: Invalid Memcached save path format: '.$this->_config['save_path']);
return $this->_failure;
return $this->_fail();
}
foreach ($matches as $match)
@@ -142,7 +142,7 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa
if (empty($server_list))
{
log_message('error', 'Session: Memcached server pool is empty.');
return $this->_failure;
return $this->_fail();
}
return $this->_success;
@@ -170,7 +170,7 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa
return $session_data;
}
return $this->_failure;
return $this->_fail();
}
// ------------------------------------------------------------------------
@@ -188,14 +188,14 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa
{
if ( ! isset($this->_memcached))
{
return $this->_failure;
return $this->_fail();
}
// Was the ID regenerated?
elseif ($session_id !== $this->_session_id)
{
if ( ! $this->_release_lock() OR ! $this->_get_lock($session_id))
{
return $this->_failure;
return $this->_fail();
}
$this->_fingerprint = md5('');
@@ -204,24 +204,33 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa
if (isset($this->_lock_key))
{
$key = $this->_key_prefix.$session_id;
$this->_memcached->replace($this->_lock_key, time(), 300);
if ($this->_fingerprint !== ($fingerprint = md5($session_data)))
{
if ($this->_memcached->set($this->_key_prefix.$session_id, $session_data, $this->_config['expiration']))
if (
$this->_memcached->replace($key, $session_data, $this->_config['expiration'])
OR ($this->_memcached->getResultCode() === Memcached::RES_NOTFOUND && $this->_memcached->set($key, $session_data, $this->_config['expiration']))
)
{
$this->_fingerprint = $fingerprint;
return $this->_success;
}
return $this->_failure;
return $this->_fail();
}
return $this->_memcached->touch($this->_key_prefix.$session_id, $this->_config['expiration'])
? $this->_success
: $this->_failure;
if (
$this->_memcached->touch($key, $this->_config['expiration'])
OR ($this->_memcached->getResultCode() === Memcached::RES_NOTFOUND && $this->_memcached->set($key, $session_data, $this->_config['expiration']))
)
{
return $this->_success;
}
}
return $this->_failure;
return $this->_fail();
}
// ------------------------------------------------------------------------
@@ -237,17 +246,17 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa
{
if (isset($this->_memcached))
{
isset($this->_lock_key) && $this->_memcached->delete($this->_lock_key);
$this->_release_lock();
if ( ! $this->_memcached->quit())
{
return $this->_failure;
return $this->_fail();
}
$this->_memcached = NULL;
return $this->_success;
}
return $this->_failure;
return $this->_fail();
}
// ------------------------------------------------------------------------
@@ -269,7 +278,7 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa
return $this->_success;
}
return $this->_failure;
return $this->_fail();
}
// ------------------------------------------------------------------------
@@ -305,9 +314,12 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa
// correct session ID.
if ($this->_lock_key === $this->_key_prefix.$session_id.':lock')
{
return ($this->_memcached->replace($this->_lock_key, time(), 300))
? $this->_success
: $this->_failure;
if ( ! $this->_memcached->replace($this->_lock_key, time(), 300))
{
return ($this->_memcached->getResultCode() === Memcached::RES_NOTFOUND)
? $this->_memcached->set($this->_lock_key, time(), 300)
: FALSE;
}
}
// 30 attempts to obtain a lock, in case another request already has it
@@ -324,7 +336,7 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa
if ( ! $this->_memcached->set($lock_key, time(), 300))
{
log_message('error', 'Session: Error while trying to obtain lock for '.$this->_key_prefix.$session_id);
return $this->_failure;
return FALSE;
}
$this->_lock_key = $lock_key;
@@ -335,11 +347,11 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa
if ($attempt === 30)
{
log_message('error', 'Session: Unable to obtain lock for '.$this->_key_prefix.$session_id.' after 30 attempts, aborting.');
return $this->_failure;
return FALSE;
}
$this->_lock = TRUE;
return $this->_success;
return TRUE;
}
// ------------------------------------------------------------------------
@@ -367,5 +379,4 @@ class CI_Session_memcached_driver extends CI_Session_driver implements SessionHa
return TRUE;
}
}
}

View File

@@ -69,6 +69,13 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle
*/
protected $_lock_key;
/**
* Key exists flag
*
* @var bool
*/
protected $_key_exists = FALSE;
// ------------------------------------------------------------------------
/**
@@ -124,7 +131,7 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle
{
if (empty($this->_config['save_path']))
{
return $this->_failure;
return $this->_fail();
}
$redis = new Redis();
@@ -146,7 +153,7 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle
return $this->_success;
}
return $this->_failure;
return $this->_fail();
}
// ------------------------------------------------------------------------
@@ -166,12 +173,17 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle
// Needed by write() to detect session_regenerate_id() calls
$this->_session_id = $session_id;
$session_data = (string) $this->_redis->get($this->_key_prefix.$session_id);
$session_data = $this->_redis->get($this->_key_prefix.$session_id);
is_string($session_data)
? $this->_key_exists = TRUE
: $session_data = '';
$this->_fingerprint = md5($session_data);
return $session_data;
}
return $this->_failure;
return $this->_fail();
}
// ------------------------------------------------------------------------
@@ -189,40 +201,41 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle
{
if ( ! isset($this->_redis))
{
return $this->_failure;
return $this->_fail();
}
// Was the ID regenerated?
elseif ($session_id !== $this->_session_id)
{
if ( ! $this->_release_lock() OR ! $this->_get_lock($session_id))
{
return $this->_failure;
return $this->_fail();
}
$this->_fingerprint = md5('');
$this->_key_exists = FALSE;
$this->_session_id = $session_id;
}
if (isset($this->_lock_key))
{
$this->_redis->setTimeout($this->_lock_key, 300);
if ($this->_fingerprint !== ($fingerprint = md5($session_data)))
if ($this->_fingerprint !== ($fingerprint = md5($session_data)) OR $this->_key_exists === FALSE)
{
if ($this->_redis->set($this->_key_prefix.$session_id, $session_data, $this->_config['expiration']))
{
$this->_fingerprint = $fingerprint;
$this->_key_exists = TRUE;
return $this->_success;
}
return $this->_failure;
return $this->_fail();
}
return ($this->_redis->setTimeout($this->_key_prefix.$session_id, $this->_config['expiration']))
? $this->_success
: $this->_failure;
: $this->_fail();
}
return $this->_failure;
return $this->_fail();
}
// ------------------------------------------------------------------------
@@ -241,10 +254,10 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle
try {
if ($this->_redis->ping() === '+PONG')
{
isset($this->_lock_key) && $this->_redis->delete($this->_lock_key);
$this->_release_lock();
if ($this->_redis->close() === $this->_failure)
{
return $this->_failure;
return $this->_fail();
}
}
}
@@ -283,7 +296,7 @@ class CI_Session_redis_driver extends CI_Session_driver implements SessionHandle
return $this->_success;
}
return $this->_failure;
return $this->_fail();
}
// ------------------------------------------------------------------------

View File

@@ -526,6 +526,12 @@ class CI_Upload {
$this->file_name = preg_replace('/\s+/', '_', $this->file_name);
}
if ($this->file_ext_tolower && ($ext_length = strlen($this->file_ext)))
{
// file_ext was previously lower-cased by a get_extension() call
$this->file_name = substr($this->file_name, 0, -$ext_length).$this->file_ext;
}
/*
* Validate the file name
* This function appends an number onto the end of

View File

@@ -65,11 +65,11 @@
<![endif]-->
<link rel="stylesheet" type="text/css" href="templates/spacelab/css/bootstrap.min.css?rel=9ed20b1ee8"/>
<!-- start mincss template tags -->
<link rel="stylesheet" type="text/css" href="dist/opensourcepos.min.css?rel=3ded88f8ce"/>
<link rel="stylesheet" type="text/css" href="dist/opensourcepos.min.css?rel=60674239d1"/>
<!-- end mincss template tags -->
<link rel="stylesheet" type="text/css" href="templates/spacelab/css/style.css"/>
<!-- start minjs template tags -->
<script type="text/javascript" src="dist/opensourcepos.min.js?rel=52d78ada05" language="javascript"></script>
<script type="text/javascript" src="dist/opensourcepos.min.js?rel=10400d243b" language="javascript"></script>
<!-- end minjs template tags -->
<?php endif; ?>