How to validate time input in Codeigniter - codeigniter

I have a text box in a form to enter time and I use to check the validation using jquery. But now I want to check the validation of the text box using the codeigniter's built-in validation system. Would you please kindly tell me how to validate time input using codeigniter's built-in validation system?
Here's the code how I use to do it using jquery:
<script type="text/javascript">
$().ready(function() {
$.validator.addMethod("time", function(value, element) {
return this.optional(element) || /^(([0-1]?[0-2])|([2][0-3])):([0-5]?[0-9])\s(a|p)m?$/i.test(value);
}, "Enter Valid Time");
$("#theForm").validate({
rules: {
time: "required time",
},
});
});
</script>
And here is the html
<input class="time" type="text" name="time1" size="15">

Something like this perhaps
// Validation rule in controller
$this->form_validation->set_rules('time', 'time', 'trim|min_length[3]|max_length[5]|callback_validate_time');
and a callback:
public function validate_time($str)
{
//Assume $str SHOULD be entered as HH:MM
list($hh, $mm) = split('[:]', $str);
if (!is_numeric($hh) || !is_numeric($mm))
{
$this->form_validation->set_message('validate_time', 'Not numeric');
return FALSE;
}
else if ((int) $hh > 24 || (int) $mm > 59)
{
$this->form_validation->set_message('validate_time', 'Invalid time');
return FALSE;
}
else if (mktime((int) $hh, (int) $mm) === FALSE)
{
$this->form_validation->set_message('validate_time', 'Invalid time');
return FALSE;
}
return TRUE;
}

Modifying what #danneth posted, in order to accept time as HH:MM:SS
public function validate_time($str){
if (strrchr($str,":")) {
list($hh, $mm, $ss) = explode(':', $str);
if (!is_numeric($hh) || !is_numeric($mm) || !is_numeric($ss)){
return FALSE;
}elseif ((int) $hh > 24 || (int) $mm > 59 || (int) $ss > 59){
return FALSE;
}elseif (mktime((int) $hh, (int) $mm, (int) $ss) === FALSE){
return FALSE;
}
return TRUE;
}else{
return FALSE;
}
}
*Changed deprecated split for explode
*Added one more condition in case the parameter received is a string like 'aaaaa'
*Changed form validation min_length from 3 to 8 (so you make sure the 8 characters from HH:MM:SS are entered):
$this->form_validation->set_rules('time','Time','required|trim|min_length[8]|max_length[8]|callback_validate_time');

have improvised #danneth 's code hope it helps
function _validate_date($str_date)
{
if($str_date!='')
{
/*
Remove Whitespaces if any
*/
$str_date = trim($str_date);
list($hh,$sub) = split('[:]', $str_date);
/*
Separate Minute from Meridian
e.g 50 PM ===> $mm=60 and $md=PM
*/
$mm = substr($sub, 0,2);
$md = trim(substr($sub, 2,strlen($sub)));
/*
Make Meridian uppercase
Implicitly Check if Meridian is PM or AM
if not then make it PM
*/
$md = strtoupper($md);
if(!in_array($md, array('PM',"AM")))
{
return FALSE;
}
/*
Check if MM and HH are numeric
*/
if(!is_numeric($hh) || !is_numeric($mm))
{
$this->form_validation->set_message('Invalid Time','Illegal chars found');
return 11;
}
$hh = (int)$hh;
$mm = (int)$mm;
/*
Check HH validity should not be less than 0 and more 24
*/
if($hh<0 || $hh>24)
{
return FALSE;
}
/*
Check MM validity should not be less than 0 and more than 59
*/
if($mm<0 | $mm>59)
{
return FALSE;
}
/*
Parse HH and MM to int for further operation and check it generates validate time
*/
if(mktime($hh,$mm)==FALSE)
{
$this->form_validation->set_message('Invalid Time','Check Time');
return FALSE;
}
return TRUE;
}
else
{
return FALSE;
}
}

Related

how to check count of likes and dislike for post for rating sysytem

i am making an system to check count of likes and dislike if like count is more then dislike count then it gives true
but i am getting an error
// if (Files::withCount('likes') >= Files::withCount('dislike')) {
// return response()->json(['true']);
// }elseif (Files::withCount('dislike') >= Files::withCount('like')) {
// return response()->json(['false']);
// }else{
// return response()->json(['error'=>'somethingwenrwrng']);
// }
// if( DB::table('files')->select('files_id')
// ->join('likes','files_id.files_id','=','files_id') > DB::table('files')->select('id')
// ->join('dislike','files_id.files_id','=','files_id') ){
// return response()->json(['true']);
// }else {
// return response()->json(['error'=>'somethingwenrwrng']);
// }
$file = Files::find($id);
if($file ->likes->count() > $file ->dislike->count() ){
return response()->json(['true']);
}else{
return response()->json(['error'=>'somethingwenrwrng']);
}
i have tried different method to check but getting an error
the withCount() method return a property of the related field_count counting related models
so
$file = Files::find($id)->withCount(['likes','dislikes']);
if($file->likes_count > $file->dislikes_count ){
return response()->json(['true']);
}

How to add another array value in codeigniter using getRecords

The orignial code was like this , I want to get landline_no value also in getRecords, How to do that
public function checklead() {
$lead = $_POST['number'];
$check = $this->common_model->getRecords('leads',array("phone_no"=>$lead));
if(count($check) > 0) {
$lead = $this->common_model->getRecored_row('leads',array("phone_no"=>$lead));
if($lead->assignto_self != 0) {
$assignto = $lead->assignto_self;
$key = 'Self Assign';
} else if($lead->assignto_se != 0) {
$assignto = $lead->assignto_se;
$key = '';}
What I have achieved so far,but not getting array values from getRecords
$lead = $_POST['number'];
$check = $this->common_model->getRecords('leads',array("phone_no"=>$lead),array("landline_no"=>$lead));
//echo "<pre>";
//print_r($check);
//echo $check[0]['landline_no'];exit;
if(count($check) > 0) {
$lead = $this->common_model->getRecored_row('leads',array("phone_no"=>$lead,"landline_no"=>$check[0]['landline_no']));
Code for getRecords:
function getRecords($table,$db = array(),$select = "*",$ordercol = '',$group = '',$start='',$limit=''){
$this->db->select($select);
if(!empty($ordercol)){
$this->db->order_by($ordercol);
}
if($limit != '' && $start !=''){
$this->db->limit($limit,$start);
}
if($group != ''){
$this->db->group_by($group);
}
$q=$this->db->get_where($table, $db);
return $q->result_array();
}
// Get Recored row
public function getRecored_row($table,$where)
{
$q = $this->db->where($where)
->select('*')
->get($table);
return $q->row();
}
Check my answer: This code also working well, i have written, but i am not sure , this logic is correct or not kindly check this one.
public function checklead() {
$lead = $_POST['number'];
if($this->common_model->getRecords('leads',array("phone_no"=>$lead)))
{
$check=$this->common_model->getRecords('leads',array("phone_no"=>$lead));
}
else
{
$check=$this->common_model->getRecords('leads',array("landline_no"=>$lead));
}
echo "<pre>";
//echo $check;
//print_r($check); exit;
$p= $check[0]['phone_no'];
$l= $check[0]['landline_no'];
// exit;
if(count($p) > 0 || count($l)>0) {
$lead = $this->common_model->getRecored_row('leads',array("phone_no"=>$p));
$lead1 = $this->common_model->getRecored_row('leads',array("landline_no"=>$l));
if($lead->assignto_self != 0 || $lead1->assignto_self != 0) {
$assignto = $lead->assignto_self;
$key = 'Self Assign';
} else if($lead->assignto_se != 0 || $lead1->assignto_se != 0) {
$assignto = $lead->assignto_se;
$key = '';
}else if($lead->assignto_tl != 0 || $lead1->assignto_tl != 0) {
$assignto = $lead->assignto_tl;
$key = '';
} else if($lead->uploaded_by != 0 || $lead1->uploaded_by != 0) {
$assignto = $lead->uploaded_by;
$key = 'Uploaded by';
}
$user = $this->common_model->getRecored_row('admin',array("id"=>$assignto));
$role = $this->common_model->getRecored_row('role',array("id"=>$user->role));
$this->session->set_flashdata('message', array('message' => 'This Lead Already exist with '.$user->name.' ('.$role->role.') '.' ','class' => 'danger'));
redirect(base_url().'leads');
} else {
redirect(base_url().'leads/add_newlead/'.$lead);
}
}
There does not seem to be any reason to use getRecords(). The $check value has no useful purpose and creating it is a waste of resources.
We don't need $check because getRecord_row() will return the "lead" if found so the only check needed is to see if getRecord_row() returns anything. getRecord_row() uses the database function row() which returns only one row or null if no rows are found. Read about row() here.
If what you want is to find the "lead" that has either a "phone_no" or a "landline_no" equal to $_POST['number'] then you need to use a custom string for the where clause. (See #4 at on this documentation page.) You need a custom string because getRecord_row() does not allow any other way to ask for rows where a='foo' OR b='foo'. Here is what I think you are looking for.
public function checklead()
{
// use input->post() it is the safe way to get data from $_POST
$phone = $this->input->post('number');
// $phone could be null if $_POST['number'] is not set
if($phone)
{
$lead = $this->common_model->getRecored_row('leads', "phone_no = $phone OR landline_no = $phone");
// $lead could be null if nothing matches where condition
if($lead)
{
if($lead->assignto_self != 0)
{
$assignto = $lead->assignto_self;
$key = 'Self Assign';
}
else if($lead->assignto_se != 0)
{
$assignto = $lead->assignto_se;
$key = '';
}
}
}
}
The main difference between getRecords() and getRecord_row() is the number of records (rows of data) to return. getRecord_row() will return a maximum of one record while getRecords() might return many records.
getRecords() accepts arguments that allow control of what data is selected ($db, $select), how it is arranged ($ordercol, $group), and the number of rows to retrieve ($limit) starting at row number x ($start) .

checkbox controller in laravel

Hello this is my controller in laravel and I am not getting the problem here. It checks the file if I manually enter a dataset with the value of 1 but if I do it with the system it does not update the value and the box remains to 0 with unchecked box.
What I am trying to do is tick the box if the user tick it and keep the box ticked until he ticks it off plus update the database value too. Thank you in advance
public function tickoffUpload($id, $type, User $user) {
$uploads = $this->upload->get($id);
// if($this->request->isMethod('get')) {
// if($user->can('untick', $uploads)) {
// $uploads = $this->upload = 0;
// } else {
// return $uploads = $this->upload = 1;
// }
// }
if($this->request->isMethod('get')) {
if($type == 0) {
$uploads = $this->upload = 1;
} else if($type == 1){
$uploads = $this->upload = 0;
}
}
if(isset($_POST["uploaded"]) && !empty($_POST["uploaded"])) {
$uploads->uploaded = $this->request->uploaded;
$uploads->save();
}
return redirect('/home');
}
I have sorted this out. I was not getting the requesting value from the form as you can see here $uploads->uploaded = $this->upload = 1; so here is the updated code which I did and worked.
public function tickoffUpload($id, $type, User $user) {
$uploads = $this->upload->get($id); //gets upload id
// requesting uploaded value either 0 or 1
if($this->request->isMethod('get')) {
if($type == 0) {
$uploads->uploaded = $this->request->upload = 1;
} else if($type == 1) {
$uploads->uploaded = $this->request->upload = 0;
}
}
$uploads->save(); // saving the value in database
return redirect('/home');
}
Thank you d3r1ck for the help though ... :)

Modify the MY_Router.php file for QUERY STRING Codeigniter 3.0.6

I use codeigniter 3.0.6 query string like
index.php?d=directoryt&c=controller
index.php?d=directory&c=controller&m=function
How ever having two get methods for directory and controller is a bit long.
Question Is there any way to modify the protected function
_set_routing() function using a MY_Router.php to get it so it will pick up the directory and controller by using one query only like example below.
index.php?route=directory/controller
// If need to get function
index.php?route=directory/controller&m=function
What have tried so far
<?php
class MY_Router extends CI_Router {
protected function _set_routing()
{
// Load the routes.php file. It would be great if we could
// skip this for enable_query_strings = TRUE, but then
// default_controller would be empty ...
if (file_exists(APPPATH.'config/routes.php'))
{
include(APPPATH.'config/routes.php');
}
if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/routes.php'))
{
include(APPPATH.'config/'.ENVIRONMENT.'/routes.php');
}
// Validate & get reserved routes
if (isset($route) && is_array($route))
{
isset($route['default_controller']) && $this->default_controller = $route['default_controller'];
isset($route['translate_uri_dashes']) && $this->translate_uri_dashes = $route['translate_uri_dashes'];
unset($route['default_controller'], $route['translate_uri_dashes']);
$this->routes = $route;
}
// Are query strings enabled in the config file? Normally CI doesn't utilize query strings
// since URI segments are more search-engine friendly, but they can optionally be used.
// If this feature is enabled, we will gather the directory/class/method a little differently
if ($this->enable_query_strings)
{
// If the directory is set at this time, it means an override exists, so skip the checks
if ( ! isset($this->directory))
{
$_route = isset($_GET['route']) ? trim($_GET['route'], " \t\n\r\0\x0B/") : '';
if ($_route !== '')
{
echo $_route;
$this->uri->filter_uri($_route);
$this->set_directory($_route);
}
}
// Routing rules don't apply to query strings and we don't need to detect
// directories, so we're done here
return;
}
// Is there anything to parse?
if ($this->uri->uri_string !== '')
{
$this->_parse_routes();
}
else
{
$this->_set_default_controller();
}
}
}
config.php
$config['allow_get_array'] = TRUE;
$config['enable_query_strings'] = TRUE;
$config['controller_trigger'] = 'c';
$config['function_trigger'] = 'm';
$config['directory_trigger'] = 'd';
// Modifyed in MY_Router.php
$config['route'] = 'route';
I have it working
<?php
class MY_Router extends CI_Router {
protected function _set_routing() {
if (file_exists(APPPATH.'config/routes.php'))
{
include(APPPATH.'config/routes.php');
}
if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/routes.php'))
{
include(APPPATH.'config/'.ENVIRONMENT.'/routes.php');
}
// Validate & get reserved routes
if (isset($route) && is_array($route))
{
isset($route['default_controller']) && $this->default_controller = $route['default_controller'];
isset($route['translate_uri_dashes']) && $this->translate_uri_dashes = $route['translate_uri_dashes'];
unset($route['default_controller'], $route['translate_uri_dashes']);
$this->routes = $route;
}
if ($this->enable_query_strings) {
if ( ! isset($this->directory))
{
$route = isset($_GET['route']) ? trim($_GET['route'], " \t\n\r\0\x0B/") : '';
if ($route !== '')
{
$part = explode('/', $route);
$this->uri->filter_uri($part[0]);
$this->set_directory($part[0]);
if ( ! empty($part[1])) {
$this->uri->filter_uri($part[1]);
$this->set_class($part[1]);
// Testing function atm
if ( ! empty($_GET['function']))
{
$this->uri->filter_uri($_GET['function']);
$this->set_method($_GET['function']);
}
$this->uri->rsegments = array(
1 => $this->class,
2 => $this->method
);
}
} else {
$this->_set_default_controller();
}
}
// Routing rules don't apply to query strings and we don't need to detect
// directories, so we're done here
return;
}
// Is there anything to parse?
if ($this->uri->uri_string !== '')
{
$this->_parse_routes();
}
else
{
$this->_set_default_controller();
}
}
}

How to set minimum upload size in codeigniter

I want to set minimum width and height for uploading images in codeigniter.
The code is shown below.
$config['max_width'] = '480';
$config['max_height'] = '270';
$this->upload->do_upload()
I have set maximum cut off for this but how to set minimum ??
Copy your Upload.php from system/libraries and paste on application/libraries. Then,
introduce 2 new variables.
public $max_width = 0;
public $max_height = 0;
public $min_width = 0; // new
public $min_height = 0; // new
Add these to the initialize function so that you can pass values through a $config variable.
Locate is_allowed_dimensions function and modify it.
if ($this->min_width > 0 AND $D['0'] < $this->min_width)
{
return FALSE;
}
if ($this->min_height > 0 AND $D['1'] < $this->min_height)
{
return FALSE;
}
Check the upload language file and alter the upload_invalid_dimensions key accordingly to fit your case.
Have not tested this, but should work :)
Go to system/validation. And then open file FileRules.php
Paste this code :
public function min_dims(?string $blank, string $params): bool
{
// Grab the file name off the top of the $params
// after we split it.
$params = explode(',', $params);
$name = array_shift($params);
if (! ($files = $this->request->getFileMultiple($name))) {
$files = [$this->request->getFile($name)];
}
foreach ($files as $file) {
if ($file === null) {
return false;
}
if ($file->getError() === UPLOAD_ERR_NO_FILE) {
return true;
}
// Get Parameter sizes
$allowedWidth = $params[0] ?? 0;
$allowedHeight = $params[1] ?? 0;
// Get uploaded image size
$info = getimagesize($file->getTempName());
$fileWidth = $info[0];
$fileHeight = $info[1];
if ($fileWidth < $allowedWidth || $fileHeight < $allowedHeight) {
return false;
}
}
return true;
}
And, in your controller use min_dims[field_name,1100,1100]. The first
parameter is the field name. The second is
the width, and the third is the height
Good Luck!
Here is the working fix, additionally you need to specify min_height and min_width while you init
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class CI_Upload {
public $max_size = 0;
public $max_width = 0;
public $max_height = 0;
public $min_width = 0;
public $min_height = 0;
public $max_filename = 0;
public $allowed_types = "";
public $file_temp = "";
public $file_name = "";
public $orig_name = "";
public $file_type = "";
public $file_size = "";
public $file_ext = "";
public $upload_path = "";
public $overwrite = FALSE;
public $encrypt_name = FALSE;
public $is_image = FALSE;
public $image_width = '';
public $image_height = '';
public $image_type = '';
public $image_size_str = '';
public $error_msg = array();
public $mimes = array();
public $remove_spaces = TRUE;
public $xss_clean = FALSE;
public $temp_prefix = "temp_file_";
public $client_name = '';
protected $_file_name_override = '';
/**
* Constructor
*
* #access public
*/
public function __construct($props = array())
{
if (count($props) > 0)
{
$this->initialize($props);
}
log_message('debug', "Upload Class Initialized");
}
// --------------------------------------------------------------------
/**
* Initialize preferences
*
* #param array
* #return void
*/
public function initialize($config = array())
{
$defaults = array(
'max_size' => 0,
'max_width' => 0,
'max_height' => 0,
'min_width' => 0,
'min_height' => 0,
'max_filename' => 0,
'allowed_types' => "",
'file_temp' => "",
'file_name' => "",
'orig_name' => "",
'file_type' => "",
'file_size' => "",
'file_ext' => "",
'upload_path' => "",
'overwrite' => FALSE,
'encrypt_name' => FALSE,
'is_image' => FALSE,
'image_width' => '',
'image_height' => '',
'image_type' => '',
'image_size_str' => '',
'error_msg' => array(),
'mimes' => array(),
'remove_spaces' => TRUE,
'xss_clean' => FALSE,
'temp_prefix' => "temp_file_",
'client_name' => ''
);
foreach ($defaults as $key => $val)
{
if (isset($config[$key]))
{
$method = 'set_'.$key;
if (method_exists($this, $method))
{
$this->$method($config[$key]);
}
else
{
$this->$key = $config[$key];
}
}
else
{
$this->$key = $val;
}
}
// if a file_name was provided in the config, use it instead of the user input
// supplied file name for all uploads until initialized again
$this->_file_name_override = $this->file_name;
}
// --------------------------------------------------------------------
/**
* Perform the file upload
*
* #return bool
*/
public function do_upload($field = 'userfile')
{
// Is $_FILES[$field] set? If not, no reason to continue.
if ( ! isset($_FILES[$field]))
{
$this->set_error('upload_no_file_selected');
return FALSE;
}
// Is the upload path valid?
if ( ! $this->validate_upload_path())
{
// errors will already be set by validate_upload_path() so just return FALSE
return FALSE;
}
// Was the file able to be uploaded? If not, determine the reason why.
if ( ! is_uploaded_file($_FILES[$field]['tmp_name']))
{
$error = ( ! isset($_FILES[$field]['error'])) ? 4 : $_FILES[$field]['error'];
switch($error)
{
case 1: // UPLOAD_ERR_INI_SIZE
$this->set_error('upload_file_exceeds_limit');
break;
case 2: // UPLOAD_ERR_FORM_SIZE
$this->set_error('upload_file_exceeds_form_limit');
break;
case 3: // UPLOAD_ERR_PARTIAL
$this->set_error('upload_file_partial');
break;
case 4: // UPLOAD_ERR_NO_FILE
$this->set_error('upload_no_file_selected');
break;
case 6: // UPLOAD_ERR_NO_TMP_DIR
$this->set_error('upload_no_temp_directory');
break;
case 7: // UPLOAD_ERR_CANT_WRITE
$this->set_error('upload_unable_to_write_file');
break;
case 8: // UPLOAD_ERR_EXTENSION
$this->set_error('upload_stopped_by_extension');
break;
default : $this->set_error('upload_no_file_selected');
break;
}
return FALSE;
}
// Set the uploaded data as class variables
$this->file_temp = $_FILES[$field]['tmp_name'];
$this->file_size = $_FILES[$field]['size'];
$this->_file_mime_type($_FILES[$field]);
$this->file_type = preg_replace("/^(.+?);.*$/", "\\1", $this->file_type);
$this->file_type = strtolower(trim(stripslashes($this->file_type), '"'));
$this->file_name = $this->_prep_filename($_FILES[$field]['name']);
$this->file_ext = $this->get_extension($this->file_name);
$this->client_name = $this->file_name;
// Is the file type allowed to be uploaded?
if ( ! $this->is_allowed_filetype())
{
$this->set_error('upload_invalid_filetype');
return FALSE;
}
// if we're overriding, let's now make sure the new name and type is allowed
if ($this->_file_name_override != '')
{
$this->file_name = $this->_prep_filename($this->_file_name_override);
// If no extension was provided in the file_name config item, use the uploaded one
if (strpos($this->_file_name_override, '.') === FALSE)
{
$this->file_name .= $this->file_ext;
}
// An extension was provided, lets have it!
else
{
$this->file_ext = $this->get_extension($this->_file_name_override);
}
if ( ! $this->is_allowed_filetype(TRUE))
{
$this->set_error('upload_invalid_filetype');
return FALSE;
}
}
// Convert the file size to kilobytes
if ($this->file_size > 0)
{
$this->file_size = round($this->file_size/1024, 2);
}
// Is the file size within the allowed maximum?
if ( ! $this->is_allowed_filesize())
{
$this->set_error('upload_invalid_filesize');
return FALSE;
}
// Are the image dimensions within the allowed size?
// Note: This can fail if the server has an open_basdir restriction.
if ( ! $this->is_allowed_dimensions())
{
$this->set_error('upload_invalid_dimensions');
return FALSE;
}
// Sanitize the file name for security
$this->file_name = $this->clean_file_name($this->file_name);
// Truncate the file name if it's too long
if ($this->max_filename > 0)
{
$this->file_name = $this->limit_filename_length($this->file_name, $this->max_filename);
}
// Remove white spaces in the name
if ($this->remove_spaces == TRUE)
{
$this->file_name = preg_replace("/\s+/", "_", $this->file_name);
}
/*
* Validate the file name
* This function appends an number onto the end of
* the file if one with the same name already exists.
* If it returns false there was a problem.
*/
$this->orig_name = $this->file_name;
if ($this->overwrite == FALSE)
{
$this->file_name = $this->set_filename($this->upload_path, $this->file_name);
if ($this->file_name === FALSE)
{
return FALSE;
}
}
/*
* Run the file through the XSS hacking filter
* This helps prevent malicious code from being
* embedded within a file. Scripts can easily
* be disguised as images or other file types.
*/
if ($this->xss_clean)
{
if ($this->do_xss_clean() === FALSE)
{
$this->set_error('upload_unable_to_write_file');
return FALSE;
}
}
/*
* Move the file to the final destination
* To deal with different server configurations
* we'll attempt to use copy() first. If that fails
* we'll use move_uploaded_file(). One of the two should
* reliably work in most environments
*/
if ( ! #copy($this->file_temp, $this->upload_path.$this->file_name))
{
if ( ! #move_uploaded_file($this->file_temp, $this->upload_path.$this->file_name))
{
$this->set_error('upload_destination_error');
return FALSE;
}
}
/*
* Set the finalized image dimensions
* This sets the image width/height (assuming the
* file was an image). We use this information
* in the "data" function.
*/
$this->set_image_properties($this->upload_path.$this->file_name);
return TRUE;
}
// --------------------------------------------------------------------
/**
* Finalized Data Array
*
* Returns an associative array containing all of the information
* related to the upload, allowing the developer easy access in one array.
*
* #return array
*/
public function data()
{
return array (
'file_name' => $this->file_name,
'file_type' => $this->file_type,
'file_path' => $this->upload_path,
'full_path' => $this->upload_path.$this->file_name,
'raw_name' => str_replace($this->file_ext, '', $this->file_name),
'orig_name' => $this->orig_name,
'client_name' => $this->client_name,
'file_ext' => $this->file_ext,
'file_size' => $this->file_size,
'is_image' => $this->is_image(),
'image_width' => $this->image_width,
'image_height' => $this->image_height,
'image_type' => $this->image_type,
'image_size_str' => $this->image_size_str,
);
}
// --------------------------------------------------------------------
/**
* Set Upload Path
*
* #param string
* #return void
*/
public function set_upload_path($path)
{
// Make sure it has a trailing slash
$this->upload_path = rtrim($path, '/').'/';
}
// --------------------------------------------------------------------
/**
* Set the file name
*
* This function takes a filename/path as input and looks for the
* existence of a file with the same name. If found, it will append a
* number to the end of the filename to avoid overwriting a pre-existing file.
*
* #param string
* #param string
* #return string
*/
public function set_filename($path, $filename)
{
if ($this->encrypt_name == TRUE)
{
mt_srand();
$filename = md5(uniqid(mt_rand())).$this->file_ext;
}
if ( ! file_exists($path.$filename))
{
return $filename;
}
$filename = str_replace($this->file_ext, '', $filename);
$new_filename = '';
for ($i = 1; $i < 100; $i++)
{
if ( ! file_exists($path.$filename.$i.$this->file_ext))
{
$new_filename = $filename.$i.$this->file_ext;
break;
}
}
if ($new_filename == '')
{
$this->set_error('upload_bad_filename');
return FALSE;
}
else
{
return $new_filename;
}
}
// --------------------------------------------------------------------
/**
* Set Maximum File Size
*
* #param integer
* #return void
*/
public function set_max_filesize($n)
{
$this->max_size = ((int) $n < 0) ? 0: (int) $n;
}
// --------------------------------------------------------------------
/**
* Set Maximum File Name Length
*
* #param integer
* #return void
*/
public function set_max_filename($n)
{
$this->max_filename = ((int) $n < 0) ? 0: (int) $n;
}
// --------------------------------------------------------------------
/**
* Set Maximum Image Width
*
* #param integer
* #return void
*/
public function set_max_width($n)
{
$this->max_width = ((int) $n < 0) ? 0: (int) $n;
}
public function set_min_width($n)
{
$this->min_width = ((int) $n < 0) ? 0: (int) $n;
}
// --------------------------------------------------------------------
/**
* Set Maximum Image Height
*
* #param integer
* #return void
*/
public function set_max_height($n)
{
$this->max_height = ((int) $n < 0) ? 0: (int) $n;
}
public function set_min_height($n)
{
$this->min_height = ((int) $n < 0) ? 0: (int) $n;
}
// --------------------------------------------------------------------
/**
* Set Allowed File Types
*
* #param string
* #return void
*/
public function set_allowed_types($types)
{
if ( ! is_array($types) && $types == '*')
{
$this->allowed_types = '*';
return;
}
$this->allowed_types = explode('|', $types);
}
// --------------------------------------------------------------------
/**
* Set Image Properties
*
* Uses GD to determine the width/height/type of image
*
* #param string
* #return void
*/
public function set_image_properties($path = '')
{
if ( ! $this->is_image())
{
return;
}
if (function_exists('getimagesize'))
{
if (FALSE !== ($D = #getimagesize($path)))
{
$types = array(1 => 'gif', 2 => 'jpeg', 3 => 'png');
$this->image_width = $D['0'];
$this->image_height = $D['1'];
$this->image_type = ( ! isset($types[$D['2']])) ? 'unknown' : $types[$D['2']];
$this->image_size_str = $D['3']; // string containing height and width
}
}
}
// --------------------------------------------------------------------
/**
* Set XSS Clean
*
* Enables the XSS flag so that the file that was uploaded
* will be run through the XSS filter.
*
* #param bool
* #return void
*/
public function set_xss_clean($flag = FALSE)
{
$this->xss_clean = ($flag == TRUE) ? TRUE : FALSE;
}
// --------------------------------------------------------------------
/**
* Validate the image
*
* #return bool
*/
public function is_image()
{
// IE will sometimes return odd mime-types during upload, so here we just standardize all
// jpegs or pngs to the same file type.
$png_mimes = array('image/x-png');
$jpeg_mimes = array('image/jpg', 'image/jpe', 'image/jpeg', 'image/pjpeg');
if (in_array($this->file_type, $png_mimes))
{
$this->file_type = 'image/png';
}
if (in_array($this->file_type, $jpeg_mimes))
{
$this->file_type = 'image/jpeg';
}
$img_mimes = array(
'image/gif',
'image/jpeg',
'image/png',
);
return (in_array($this->file_type, $img_mimes, TRUE)) ? TRUE : FALSE;
}
// --------------------------------------------------------------------
/**
* Verify that the filetype is allowed
*
* #return bool
*/
public function is_allowed_filetype($ignore_mime = FALSE)
{
if ($this->allowed_types == '*')
{
return TRUE;
}
if (count($this->allowed_types) == 0 OR ! is_array($this->allowed_types))
{
$this->set_error('upload_no_file_types');
return FALSE;
}
$ext = strtolower(ltrim($this->file_ext, '.'));
if ( ! in_array($ext, $this->allowed_types))
{
return FALSE;
}
// Images get some additional checks
$image_types = array('gif', 'jpg', 'jpeg', 'png', 'jpe');
if (in_array($ext, $image_types))
{
if (getimagesize($this->file_temp) === FALSE)
{
return FALSE;
}
}
if ($ignore_mime === TRUE)
{
return TRUE;
}
$mime = $this->mimes_types($ext);
if (is_array($mime))
{
if (in_array($this->file_type, $mime, TRUE))
{
return TRUE;
}
}
elseif ($mime == $this->file_type)
{
return TRUE;
}
return FALSE;
}
// --------------------------------------------------------------------
/**
* Verify that the file is within the allowed size
*
* #return bool
*/
public function is_allowed_filesize()
{
if ($this->max_size != 0 AND $this->file_size > $this->max_size)
{
return FALSE;
}
else
{
return TRUE;
}
}
// --------------------------------------------------------------------
/**
* Verify that the image is within the allowed width/height
*
* #return bool
*/
public function is_allowed_dimensions()
{
if ( ! $this->is_image())
{
return TRUE;
}
if (function_exists('getimagesize'))
{
$D = #getimagesize($this->file_temp);
if ($this->max_width > 0 AND $D['0'] > $this->max_width)
{
return FALSE;
}
if ($this->max_height > 0 AND $D['1'] > $this->max_height)
{
return FALSE;
}
if ($D['0'] < $this->min_width)
{
return FALSE;
}
if ($D['1'] < $this->min_height)
{
return FALSE;
}
return TRUE;
}
return TRUE;
}
// --------------------------------------------------------------------
/**
* Validate Upload Path
*
* Verifies that it is a valid upload path with proper permissions.
*
*
* #return bool
*/
public function validate_upload_path()
{
if ($this->upload_path == '')
{
$this->set_error('upload_no_filepath');
return FALSE;
}
if (function_exists('realpath') AND #realpath($this->upload_path) !== FALSE)
{
$this->upload_path = str_replace("\\", "/", realpath($this->upload_path));
}
if ( ! #is_dir($this->upload_path))
{
$this->set_error('upload_no_filepath');
return FALSE;
}
if ( ! is_really_writable($this->upload_path))
{
$this->set_error('upload_not_writable');
return FALSE;
}
$this->upload_path = preg_replace("/(.+?)\/*$/", "\\1/", $this->upload_path);
return TRUE;
}
// --------------------------------------------------------------------
/**
* Extract the file extension
*
* #param string
* #return string
*/
public function get_extension($filename)
{
$x = explode('.', $filename);
return '.'.end($x);
}
// --------------------------------------------------------------------
/**
* Clean the file name for security
*
* #param string
* #return string
*/
public function clean_file_name($filename)
{
$bad = array(
"<!--",
"-->",
"'",
"<",
">",
'"',
'&',
'$',
'=',
';',
'?',
'/',
"%20",
"%22",
"%3c", // <
"%253c", // <
"%3e", // >
"%0e", // >
"%28", // (
"%29", // )
"%2528", // (
"%26", // &
"%24", // $
"%3f", // ?
"%3b", // ;
"%3d" // =
);
$filename = str_replace($bad, '', $filename);
return stripslashes($filename);
}
// --------------------------------------------------------------------
/**
* Limit the File Name Length
*
* #param string
* #return string
*/
public function limit_filename_length($filename, $length)
{
if (strlen($filename) < $length)
{
return $filename;
}
$ext = '';
if (strpos($filename, '.') !== FALSE)
{
$parts = explode('.', $filename);
$ext = '.'.array_pop($parts);
$filename = implode('.', $parts);
}
return substr($filename, 0, ($length - strlen($ext))).$ext;
}
// --------------------------------------------------------------------
/**
* Runs the file through the XSS clean function
*
* This prevents people from embedding malicious code in their files.
* I'm not sure that it won't negatively affect certain files in unexpected ways,
* but so far I haven't found that it causes trouble.
*
* #return void
*/
public function do_xss_clean()
{
$file = $this->file_temp;
if (filesize($file) == 0)
{
return FALSE;
}
if (function_exists('memory_get_usage') && memory_get_usage() && ini_get('memory_limit') != '')
{
$current = ini_get('memory_limit') * 1024 * 1024;
// There was a bug/behavioural change in PHP 5.2, where numbers over one million get output
// into scientific notation. number_format() ensures this number is an integer
// http://bugs.php.net/bug.php?id=43053
$new_memory = number_format(ceil(filesize($file) + $current), 0, '.', '');
ini_set('memory_limit', $new_memory); // When an integer is used, the value is measured in bytes. - PHP.net
}
// If the file being uploaded is an image, then we should have no problem with XSS attacks (in theory), but
// IE can be fooled into mime-type detecting a malformed image as an html file, thus executing an XSS attack on anyone
// using IE who looks at the image. It does this by inspecting the first 255 bytes of an image. To get around this
// CI will itself look at the first 255 bytes of an image to determine its relative safety. This can save a lot of
// processor power and time if it is actually a clean image, as it will be in nearly all instances _except_ an
// attempted XSS attack.
if (function_exists('getimagesize') && #getimagesize($file) !== FALSE)
{
if (($file = #fopen($file, 'rb')) === FALSE) // "b" to force binary
{
return FALSE; // Couldn't open the file, return FALSE
}
$opening_bytes = fread($file, 256);
fclose($file);
// These are known to throw IE into mime-type detection chaos
// <a, <body, <head, <html, <img, <plaintext, <pre, <script, <table, <title
// title is basically just in SVG, but we filter it anyhow
if ( ! preg_match('/<(a|body|head|html|img|plaintext|pre|script|table|title)[\s>]/i', $opening_bytes))
{
return TRUE; // its an image, no "triggers" detected in the first 256 bytes, we're good
}
else
{
return FALSE;
}
}
if (($data = #file_get_contents($file)) === FALSE)
{
return FALSE;
}
$CI =& get_instance();
return $CI->security->xss_clean($data, TRUE);
}
// --------------------------------------------------------------------
/**
* Set an error message
*
* #param string
* #return void
*/
public function set_error($msg)
{
$CI =& get_instance();
$CI->lang->load('upload');
if (is_array($msg))
{
foreach ($msg as $val)
{
$msg = ($CI->lang->line($val) == FALSE) ? $val : $CI->lang->line($val);
$this->error_msg[] = $msg;
log_message('error', $msg);
}
}
else
{
$msg = ($CI->lang->line($msg) == FALSE) ? $msg : $CI->lang->line($msg);
$this->error_msg[] = $msg;
log_message('error', $msg);
}
}
// --------------------------------------------------------------------
/**
* Display the error message
*
* #param string
* #param string
* #return string
*/
public function display_errors($open = '<p>', $close = '</p>')
{
$str = '';
foreach ($this->error_msg as $val)
{
$str .= $open.$val.$close;
}
return $str;
}
// --------------------------------------------------------------------
/**
* List of Mime Types
*
* This is a list of mime types. We use it to validate
* the "allowed types" set by the developer
*
* #param string
* #return string
*/
public function mimes_types($mime)
{
global $mimes;
if (count($this->mimes) == 0)
{
if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/mimes.php'))
{
include(APPPATH.'config/'.ENVIRONMENT.'/mimes.php');
}
elseif (is_file(APPPATH.'config/mimes.php'))
{
include(APPPATH.'config//mimes.php');
}
else
{
return FALSE;
}
$this->mimes = $mimes;
unset($mimes);
}
return ( ! isset($this->mimes[$mime])) ? FALSE : $this->mimes[$mime];
}
// --------------------------------------------------------------------
/**
* Prep Filename
*
* Prevents possible script execution from Apache's handling of files multiple extensions
* http://httpd.apache.org/docs/1.3/mod/mod_mime.html#multipleext
*
* #param string
* #return string
*/
protected function _prep_filename($filename)
{
if (strpos($filename, '.') === FALSE OR $this->allowed_types == '*')
{
return $filename;
}
$parts = explode('.', $filename);
$ext = array_pop($parts);
$filename = array_shift($parts);
foreach ($parts as $part)
{
if ( ! in_array(strtolower($part), $this->allowed_types) OR $this->mimes_types(strtolower($part)) === FALSE)
{
$filename .= '.'.$part.'_';
}
else
{
$filename .= '.'.$part;
}
}
$filename .= '.'.$ext;
return $filename;
}
// --------------------------------------------------------------------
/**
* File MIME type
*
* Detects the (actual) MIME type of the uploaded file, if possible.
* The input array is expected to be $_FILES[$field]
*
* #param array
* #return void
*/
protected function _file_mime_type($file)
{
// We'll need this to validate the MIME info string (e.g. text/plain; charset=us-ascii)
$regexp = '/^([a-z\-]+\/[a-z0-9\-\.\+]+)(;\s.+)?$/';
/* Fileinfo extension - most reliable method
*
* Unfortunately, prior to PHP 5.3 - it's only available as a PECL extension and the
* more convenient FILEINFO_MIME_TYPE flag doesn't exist.
*/
if (function_exists('finfo_file'))
{
$finfo = finfo_open(FILEINFO_MIME);
if (is_resource($finfo)) // It is possible that a FALSE value is returned, if there is no magic MIME database file found on the system
{
$mime = #finfo_file($finfo, $file['tmp_name']);
finfo_close($finfo);
/* According to the comments section of the PHP manual page,
* it is possible that this function returns an empty string
* for some files (e.g. if they don't exist in the magic MIME database)
*/
if (is_string($mime) && preg_match($regexp, $mime, $matches))
{
$this->file_type = $matches[1];
return;
}
}
}
/* This is an ugly hack, but UNIX-type systems provide a "native" way to detect the file type,
* which is still more secure than depending on the value of $_FILES[$field]['type'], and as it
* was reported in issue #750 (https://github.com/EllisLab/CodeIgniter/issues/750) - it's better
* than mime_content_type() as well, hence the attempts to try calling the command line with
* three different functions.
*
* Notes:
* - the DIRECTORY_SEPARATOR comparison ensures that we're not on a Windows system
* - many system admins would disable the exec(), shell_exec(), popen() and similar functions
* due to security concerns, hence the function_exists() checks
*/
if (DIRECTORY_SEPARATOR !== '\\')
{
$cmd = 'file --brief --mime ' . escapeshellarg($file['tmp_name']) . ' 2>&1';
if (function_exists('exec'))
{
/* This might look confusing, as $mime is being populated with all of the output when set in the second parameter.
* However, we only neeed the last line, which is the actual return value of exec(), and as such - it overwrites
* anything that could already be set for $mime previously. This effectively makes the second parameter a dummy
* value, which is only put to allow us to get the return status code.
*/
$mime = #exec($cmd, $mime, $return_status);
if ($return_status === 0 && is_string($mime) && preg_match($regexp, $mime, $matches))
{
$this->file_type = $matches[1];
return;
}
}
if ( (bool) #ini_get('safe_mode') === FALSE && function_exists('shell_exec'))
{
$mime = #shell_exec($cmd);
if (strlen($mime) > 0)
{
$mime = explode("\n", trim($mime));
if (preg_match($regexp, $mime[(count($mime) - 1)], $matches))
{
$this->file_type = $matches[1];
return;
}
}
}
if (function_exists('popen'))
{
$proc = #popen($cmd, 'r');
if (is_resource($proc))
{
$mime = #fread($proc, 512);
#pclose($proc);
if ($mime !== FALSE)
{
$mime = explode("\n", trim($mime));
if (preg_match($regexp, $mime[(count($mime) - 1)], $matches))
{
$this->file_type = $matches[1];
return;
}
}
}
}
}
// Fall back to the deprecated mime_content_type(), if available (still better than $_FILES[$field]['type'])
if (function_exists('mime_content_type'))
{
$this->file_type = #mime_content_type($file['tmp_name']);
if (strlen($this->file_type) > 0) // It's possible that mime_content_type() returns FALSE or an empty string
{
return;
}
}
$this->file_type = $file['type'];
}
// --------------------------------------------------------------------
}

Resources