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.
Related
I have some problem with routing and parameters.
I have routing in routes.php like this :
$route['register/(:any)'] = 'member/register/$1';
And in my controller I have like this :
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Register extends CI_Controller
{
function __construct()
{
parent::__construct();
$this->load->model('Page_model');
$this->load->model('member_model');
$this->load->model('login_model');
$this->load->library('session');
$this->load->helper('url');
$this->load->helper('html');
$this->load->helper('form');
}
public function index()
{
$slug = $this->uri->segment(1);
$type = $this->uri->segment(2);
var_dump($type);
exit();
if ($slug != NULL)
{
$data['page'] = $this->Page_model->get_page($slug);
if (empty($data['page']))
{
// show_404();
$data['page'] = new stdClass();
$data['page']->page_template = 'forofor';
$data['page']->title = 'Page Not Found';
$data['page']->meta_description = 'Page Not Found';
$data['page']->meta_keywords = 'Page Not Found';
}
else
{
$data['slider'] = $this->Page_model->get_slider($data['page']->page_id);
}
}
else
{
$data['page'] = $this->Page_model->get_page('home');
$data['slider'] = $this->Page_model->get_slider($data['page']->page_id);
}
$data['head_title'] = $data['page']->title;
// load all settings and data
$data['settings'] = $this->Page_model->get_settings();
$data['gallery'] = $this->Page_model->get_gallery();
$data['meta'] =
array(
array(
'name' => 'description',
'content' => $data['page']->meta_description
),
array(
'name' => 'keywords',
'content' => $data['page']->meta_keywords
)
);
// $data['meta'] = $this->meta;
$data['menu'] = $this->Page_model->get_menu('frontend','header');
$data['settings'] = $this->Page_model->get_settings();
$data['notice'] = $this->session->flashdata('notice');
// $this->load->view('frontend/template/index_full', $data);
$this->load->view('frontend/template/head', $data);
$this->load->view('frontend/template/pre_header');
$this->load->view('frontend/template/header');
$this->load->view('frontend/template/modal');
//$this->load->view('frontend/template/modal_registration');
/*if ($page[0]->page_template != 'forofor' && $data['page']->slider != 0)
{
$this->load->view('frontend/template/slider');
}*/
if ($slug != 'home' && $slug != NULL)
{
//$this->load->view('member/'.$data['page']->page_template);
$this->load->view('member/register');
}
else
{
$this->load->view('frontend/template/slider');
$this->load->view('frontend/page_template/homepage');
}
$this->load->view('frontend/template/pre_footer');
$this->load->view('frontend/template/footer');
$this->load->view('frontend/template/js');
$this->load->view('frontend/template/closing_body_html');
}
}
But if I input the routes in my browser it gives me 404 Page not found
This is my routes :
127.0.0.1/project/register/buyer
And 127.0.0.1/project/ is my Base URL
Anyone knows why it could be happen ?
Thank you.
Your routing is wrong. According to your post you are setting Member controller then register method.
Try below code
$route['register/(:any)'] = 'register/index/$1';
$route['register/(:any)/(:any)'] = 'register/index/$1/$2'; // Optional
The second option is only optional:
This is how routes work in Codeigniter
Typically there is a one-to-one relationship between a URL string and
its corresponding controller class/method. The segments in a URI
normally follow this pattern:
example.com/class/function/id/ In some instances, however, you may
want to remap this relationship so that a different class/method can
be called instead of the one corresponding to the URL.
For example, let’s say you want your URLs to have this prototype:
example.com/product/1/ example.com/product/2/ example.com/product/3/
example.com/product/4/ Normally the second segment of the URL is
reserved for the method name, but in the example above it instead has
a product ID. To overcome this, CodeIgniter allows you to remap the
URI handler.
Reference : https://www.codeigniter.com/userguide3/general/routing.html
So,the routes follow this syntax
$route['route_url'] = 'controller/method/$paramater';
So,your route will be
Let me know your queries
$route['register/(:any)'] = 'register/index/$1';
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;
}
}
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
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.
I searched the whole Internet and either there is no one mentioning my problem, or I'm stupid, or maybe it's just a bad day for coding.
What's the situation:
controller "source"
model "source"
model "login"
The "login" model is loaded from autoload.php, then in each controller's constructor I have $this->login->check(), which is checking if the user is logged in (obviously). Then in some of the methods I'm using the "source" model to connect to the database.
I tried loading both of the models from the autoload array, I also tried to load them in the way described here, but it's obviously for an old CI version (the thread is from 2008) and I tried all the possible ways I had in my mind.
Anyway, the result is this:
A PHP Error was encountered
Severity: Notice
Message: Undefined property: Source::$login
Filename: controllers/source.php
Line Number: 10
Fatal error: Call to a member function check() on a non-object in ...\application\controllers\source.php on line 10
Any ideas what I'm missing or how to fix it...? I'm stuck for hours and I don't have any ideas what I could do...
Edit 1: here is the code from the "source" controller:
class Source extends CI_Controller {
function __construct() {
parent::__construct();
$this->load->model('login');
$this->login->check();
}
function index() {
// Pagination config, getting records from DB
$this->load->view('templates/layout', $data);
}
function add() {
$this->load->model('source', '', true);
$btn = $this->input->post('btn');
if(isset($btn)) {
// More form validation
if($this->form_validation->run() == TRUE) {
if($btn == "Add") {
// here I am supposed to use the source model...
}
}
}
$data['page'] = 'source_add';
$this->load->view('templates/layout', $data);
}
}
?>
Edit 2: login.php:
<?php
class Login extends CI_Model {
function __construct() {
parent::__construct();
}
function authenticate($username, $password) {
// the login script comes here
}
function logged() {
if($this->session->userdata('logged') == true) {
return true;
} else return false;
}
function check() {
if(!$this->logged()) {
redirect('/authentication');
}
}
}
?>
Conventionally, the classname of Models should end with _model, so it not collides with controllers with the same name, so try changing
class Login extends CI_Model {
to
class Login_model extends CI_Model {
I resolved this issue by utilizing the hooks and turned the login process into a controller, thereby being able to access user information and setting access levels.
First I added the following to the hooks.php file in the config folder
$hook['post_controller_constructor'][] = array('function' => 'check_login','filename' => 'authority.php','filepath' => 'hooks');
Then I have the following functions in a hook file called authority.php
[EDIT]Having reviewed this I am going to change it to a pre_controller_constructor and see if I can remove what seems to be a double page flash on initial construct.[/EDIT]
function check_login(){
$CI =& get_instance();
$is_logged_in = $CI->session->userdata('is_logged_in');
if(!$is_logged_in){
$unauth_pages = array(your unauthorized pages go here);
if(!in_array($CI->router->class,$unauth_pages)){
$CI->session->set_userdata('before_login_url',current_url());
redirect('login');
}
}
}
function check_authority(){
$CI =& get_instance();
if($CI->session->userdata('usergroupID') == 'SUPADMIN'){return;}
$page = $CI->router->class ;
$method = $CI->router->method;
$method = ($method=='index')?'':$method;
$unauth_pages = array(your unauthorized pages go here);
if(in_array($page,$unauth_pages))return;
$user_group = $CI->session->userdata('usergroupID');
$CI->load->model('user_model');
if($user_group == 'ADMIN' || $user_group == 'USER'){
if($CI->session->userdata('timezone') == ''){
date_default_timezone_set('Canada/Pacific');
} else {
date_default_timezone_set($CI->session->userdata('timezone'));
}
}
if( !$CI->user_model->authorized_content($CI->session->userdata('usergroupID'),$page, $method)){
redirect('unauthorized');
}
}
With the above I dont have to worry about checking on each page but instead utilize the ci framework to do the checking for me.. if its not in the unauth page array then it is a page that requires authorization checking.
Hope this works for you.