Callback set_message not working with multidimensional array post - codeigniter

On my codeigniter project my callback is not working as would like with my multidimensional array post
I am trying on my callback set message $key['image'] to display correct value of the multidimensional array post. But when I var dump it returns NULL
On my set rules the multidimensional array validation works.
But for some reason the $key['image'] on my callback function
set_message('banner_image_regex', 'This banner' .' '. $key['image'] .' '. 'image contains a underscore cannot upload file.') not picking up.
Question on my callback function banner_image_regex() how can I make $key['image'] pick up the post value and display it.
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Banner_add extends MX_Controller {
public function __construct() {
parent::__construct();
}
public function index() {
$data['title'] = "Banner Add";
$this->load->library('form_validation');
$this->form_validation->set_rules('banner_name', 'Banner Name', 'required|callback_validate_form');
$this->form_validation->set_rules('banner_status', 'Banner Status', 'required');
if (!empty($this->input->post('banner_image'))) {
foreach ($this->input->post('banner_image') as $key => $value) {
$this->form_validation->set_rules('banner_image['.$key.'][image]', 'Banner Image', 'callback_banner_image_regex');
}
}
if ($this->form_validation->run($this) == FALSE) {
$this->load->view('template/banner/banner_add', $data);
} else {
redirect('admin/banner/banner_list');
}
}
public function banner_image_regex() {
$banner_image = $this->input->post('banner_image');
foreach ($banner_image as $key => $value) {
if (preg_match('/^[a-z0-9]+$/', $key['image'])) {
return TRUE;
} else {
$this->form_validation->set_message('banner_image_regex', 'This banner' .' '. $key['image'] .' '. 'image contains a underscore cannot upload file.');
return FALSE;
}
}
}
}

Asuming you were following CI specs about naming array fields in form validation,
you are already sending specific value (string/image name) to callback function.
So it need to be like:
public function banner_image_regex($image_name) {
if (preg_match('/^[a-z0-9]+$/', $image_name)) {
return TRUE;
} else {
$this->form_validation->set_message('banner_image_regex', 'This banner' .' '. $image_name .' '. 'image contains a underscore cannot upload file.');
return FALSE;
}
}

Related

How to fix error: count(): Parameter must be an array or an object that implements Countable

A PHP Error was encountered
Severity: Warning
Message: count(): Parameter must be an array or an object that implements Countable
Filename: models/login_model.php
Line Number: 17
Backtrace:
File: C:\xampp\htdocs\labexercise007\application\models\login_model.php
Line: 17
Function: _error_handler
File: C:\xampp\htdocs\labexercise007\application\controllers\login.php
Line: 31
Function: login
File: C:\xampp\htdocs\labexercise007\application\controllers\login.php
Line: 14
Function: run
<?php
class login_model extends CI_Model
{
public function __construct()
{
parent::__construct();
$this->load->database();
}
public function login($username, $password)
{
$condition_array = array(
'user_name' => $username,
'user_pass' => md5($password)
);
$rs = $this->db->get_where('users', $condition_array);
$row_count = count($rs->row_array());
if ($row_count > 0) {
return $rs->row_array();
} else {
return FALSE;
}
}
}
<?php
class Login extends CI_Controller
{
public function index()
{
$data['title'] = 'Login';
$this->load->view('login', $data);
}
public function verify()
{
$this->form_validation->set_rules('txtuser', 'Username', 'required');
$this->form_validation->set_rules('txtpass', 'Password', 'required|callback_check_user');
if ($this->form_validation->run() === TRUE) {
if ($this->session->user_lvl == 1) {
redirect('admin/home');
} else {
redirect('home');
}
} else {
$this->index();
}
}
public function check_user()
{
$username = $this->input->post('txtuser');
$password = $this->input->post('txtpass');
$this->load->model('login_model');
$login = $this->login_model->login($username, $password);
if ($login) {
$sess_data = array(
'account_name' => $login['user_accountname'],
'user_lvl' => $login['user_lvl'],
'islogged' => TRUE
);
$this->session->set_userdata($sess_data);
return true;
} else {
$this->form_validation->set_message('check_user', 'Invalid Username/password');
return false;
}
}
}
PHP v7.2.0 count() will now yield a warning on invalid countable types passed to the array_or_countable parameter.
see more
If your result set is empty, the row_array() value is NULL and you cannot use count on it. Check what row_array() returns before counting.
Later edit
Try removing this block:
if ($row_count > 0) {
return $rs->row_array();
} else {
return FALSE;
}
And replacing it with a ternary operator call:
return $rs->row_array() ?: false;
This should solve your warning and return the proper result.
Did you try to get the result array? in the documentation in query builder it gives like this.
$row_count = count($rs->getResultArray()) ;
in this case it will always return an array even if you do not have a result in query.
Instead of counting the row array that might be null in your case so you don't have a countable object or array you should count your query results.
$row_count = count($rs->row_array());
Instead use the count records function built in the query builder.
public function login($username, $password)
{
$condition_array = array(
'user_name' => $username,
'user_pass' => md5($password)
);
$rs = $this->db->from('users')->where($condition_array)->get();
$row_count = $this->db->num_rows();
if ($row_count > 0) {
return $rs->row_array();
}
return FALSE;
}
Changed the function to remove the else statement because it was not needed in this case.
Also, I might add that you shouldn't be using MD5 to encrypt your passwords. MD5 is not really secure at this point.
More information on counting database results on codeigniter 3: https://codeigniter.com/userguide3/database/query_builder.html?highlight=count#limiting-or-counting-results
In Model:
function getPaymentTotalCount($search)
{
$sql = 'SELECT id FROM tbl_payment WHERE '.$search;
$query = $this->db->query($sql);
return $query->num_rows(); // <- replace row() to num_rows()
}

how to send more than 1 parameter in set rules to a public function in codeIgniter

reference link is this:
Check duplicate data in CodeIgniter try to make a callback function
and this is my controller:
function saveData(){
$value = $this->input->post('Id');
$fromtable = 'tbl_tablename';
$fromwhere = 'Id';
$this->form_validation->set_rules('productId', '', 'callback_check_duplicate_record[' . $value,$fromtable,$fromwhere . ']');
if ($this->form_validation->run() == FALSE) {
$this->session->set_flashdata('error', 'Record already exists.');
redirect('addNew');
return;
}
}
public function check_duplicate_record($value,$fromtable,$fromwhere) {
return $this->user_model->checkRecordExists($value,$fromtable,$fromwhere);
}
this works fine with 1 parameter, but how to send 3 parameters.
where am I doing wrong.
you aren't doing anything wrong per-say, it's just that the callback function is only designed to handle 1 parameter.
since two of your values are hard-coded you don't really need to pass them technically.
$this->form_validation->set_rules('productId', '', 'callback_check_duplicate_record[' . $value . ']');
public function check_duplicate_record($value) {
$fromtable = 'tbl_tablename';
$fromwhere = 'Id';
return $this->user_model->checkRecordExists($value,$fromtable,$fromwhere);
}
and to be honest it doesn't even look like you need form validation as your only validator is the callback, just use that:
if (!$this->user_model->checkRecordExists($value,$fromtable,$fromwhere)) {
$this->session->set_flashdata('error', 'Record already exists.');
redirect('addNew');
return;
}

Is it possible to have global class variables in CodeIgniter?

I am developing an application in CodeIgniter that has a member login system. I have a model that gets all the information of a requested member.
class Member extends CI_Model {
var $info = array();
var $error = NULL;
function __construct(){
parent::__construct();
}
public function get_info($member_id = ''){
$this->db->where('member_id', $member_id);
$this->db->limit(1);
$query = $this->db->get('members');
if($query->num_rows() > 0){
$member = $query->row_array();
$info = array(
'id' => $member['member_id'],
'display_name' => $member['display_name'],
'email_address' => $member['email_address'],
'password' => $member['password'],
'status' => ($member['status'] == 0) ? FALSE : TRUE,
'activation_code' => $member['activation_code'],
'location' => $member['location'],
'date_joined' => date('M jS, Y', $member['date_joined']),
'gender' => ($member['gender'] == 0) ? 'Male' : 'Female',
'results_per_page' => $member['results_per_page'],
'admin_emails' => ($member['admin_emails'] == 0) ? FALSE : TRUE,
'member_emails' => ($member['member_emails'] == 0) ? FALSE : TRUE
);
$this->info = $info;
} else {
$this->error = 'The member you requested could not be found in our database.';
}
}
At the top of my controllers and other models, I use the following to get the information of the current user to pass it along to all of the methods.
function __construct(){
parent::__construct();
$this->member->get_info($this->session->userdata('member_id'));
$this->user = $this->member->info;
}
function index(){
if($this->user['id'] > 0){
echo "You are logged in!";
} else {
echo "You are NOT logged in!";
}
}
Is there a way to do this on a global scale? It's kind of tiresome to type out the construct code at the top of every controller.
So I managed to find another post here on StackOverflow that solved my problem.
enter link description here
In application/core, I extended the existing Controller and Model classes with a few additions. Then I had to change my controllers and models to suit.
class Home extends MY_Controller {
}
application/core/MY_Model.php
class MY_Model extends CI_Model {
var $user = array();
function __construct(){
parent::__construct();
$this->load->model('member');
$this->member->get_info($this->session->userdata('member_id'));
$this->user = $this->member->info;
}
}
application/core/MY_Controller.php
class MY_Controller extends CI_Controller {
var $user = array();
function __construct(){
parent::__construct();
$this->load->model('member');
$this->member->get_info($this->session->userdata('member_id'));
$this->user = $this->member->info;
}
}
In construct simply try to access session data
function __construct() {
if($this->session->userdata('member_id')) {
echo 'You are logged in';
} else {
echo 'You are not logged in';
}
}
It is simple rather than getting all the data and selecting 'user id',if we check whether ths session data is there then a user is logged in orelse no one is logged.You can add this at your each controller construct function and you can check without help of any DB

Handle CodeIgniter remapping with parameters

I have the following code I added to a MY_Controller that is being extended by all my controllers:
public function _remap($method, $params = array())
{//exit($this->router->fetch_class());
if (array_search($method, $this->private_methods) !== false && !$this->logged_in)
{
$this->session->set_flashdata('message', array(
'message' => 'You must login to access the requested area',
'error' => 1
)
);
redirect('/');
}
else if (method_exists($this, $method))
{
$this->$method($params);
}
else
{
redirect('/');
}
}
The issue being created is that the call $this->$method($params) is condensing the params in to an Array. So a method such as the following breaks:
function some_method($param1, $param2, $param3)
Is there a way to break this array back into individual items for functions like this?
I was trying to do the same and find the same problem with
$this->$method($params);
I found another option
call_user_method_array($method,$this,$params);
Which worked but is already deprecated.
Function in PHP deprecated, what should I use now?
But hopefully that is the new one.
call_user_func_array(array($this,$method), $params);
I have tried this and it worked for me
public function _remap($method,$params = array())
{
if (method_exists($this, $method)) {
if($method == 'delete_photo' || $method == 'delete_video'){
call_user_func_array(array($this,$method), $params);
}
else{
$this->$method();
}
}
else {
$this->index($method);
}
}
Now you just have to replace "delete_photo" & "delete_video" with your methods names that contains parameters, and of course you can add as much methods as you want.

Codeigniter validation library extension is not working

I have extended CI form validation library as following:
class MY_Form_validation extends CI_Form_validation {
function __construct($config = array())
{
parent::__construct($config);
}
function check_first_char($str)
{
$CI =& get_instance();
$first_char = substr($str, 0, 1);
if ($first_char != 'P' || $first_char != 'S')
{
$CI->form_validation->set_message('check_first_char', 'The %s field must begin with P or S!');
return FALSE;
}
else {
return TRUE;
}
}
and calling it like following:
$this->form_validation->set_rules('sponsor_id', 'Sponsor ID', 'trim|required|exact_length[7]|check_first_char');
But it is not working. What I am doing wrong?
Make sure to initialize the library in your controller:
$this->load->library('form_validation');
$this->form_validation->set_rules('sponsor_id', 'Sponsor ID', 'trim|required|exact_length[7]|callback_check_first_char');
If i'm not mistaken, you'll need the 'callback_'
Source: http://codeigniter.com/user_guide/libraries/form_validation.html
Edit: And you'll also need to initialise the form_validation library.

Resources