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
Related
The problem is when I entered a new name no data is added. A similar thing happen when I entered an already existing name. Still, no data is added to the database. I am still new to CodeIgniter and not entirely sure my query builder inside the model is correct or not.
In the Model, I check if the name already exists insert data only into the phone_info table. IF name does not exist I insert data into user_info and phone_info.
Controller:
public function addData()
{
$name = $this->input->post('name');
$contact_num = $this->input->post('contact_num');
if($name == '') {
$result['message'] = "Please enter contact name";
} elseif($contact_num == '') {
$result['message'] = "Please enter contact number";
} else {
$result['message'] = "";
$data = array(
'name' => $name,
'contact_num' => $contact_num
);
$this->m->addData($data);
}
echo json_encode($result);
}
Model:
public function addData($data)
{
if(mysqli_num_rows($data['name']) > 0) {
$user = $this->db->get_where('user_info', array('name' => $data['name']))->result_array();
$user_id = $user['id'];
$phone_info = array(
'contact_num' => $data['contact_num'],
'user_id' => $user_id
);
$this->db->insert('phone_info',$phone_info);
} else {
$user_info = array(
'name' => $data['name']
);
$this->db->insert('user_info', $user_info);
$user = $this->db->get_where('user_info', array('name' => $data['name']))->result_array();
$user_id = $user['id'];
$phone_info = array(
'contact_num' => $data['contact_num'],
'user_id' => $user_id
);
$this->db->insert('phone_info', $phone_info);
}
}
DB-Table user_info:
DB-Table phone_info:
Extend and change your model to this:
public function findByTitle($name)
{
$this->db->where('name', $name);
return $this->result();
}
public function addData($data)
{
if(count($this->findByTitle($data['name'])) > 0) {
//.. your code
} else {
//.. your code
}
}
Explanation:
This:
if(mysqli_num_rows($data['name']) > 0)
..is not working to find database entries by name. To do this you can use codeigniters built in model functions and benefit from the MVC Pattern features, that CodeIgniter comes with.
I wrapped the actual findByName in a function so you can adapt this to other logic and use it elswehere later on. This function uses the query() method.
Read more about CodeIgniters Model Queries in the documentation.
Sidenote: mysqli_num_rows is used to iterate find results recieved by mysqli_query. This is very basic sql querying and you do not need that in a MVC-Framework like CodeIgniter. If you every appear to need write a manual sql-query, even then you should use CodeIgniters RawQuery methods.
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()
}
I use Laravel 7.
I build some apis in which the "GET" result depends on the request. For example
/schools?fields=name,id,school_type_id
means "give me all the schools, but only the name + id + school_type_id".
/schools?
means "give me all the schools, all the columns".
To do that I am using a resource :
class SchoolResource extends JsonResource
{
public function toArray($request)
{
$fields = $request->has('fields') ? explode(',', $request->fields) : [];
return [
'id' => $this->when(0 === \count($fields) || \in_array('id', $fields, true), $this->id),
'name' => $this->when(0 === \count($fields) || \in_array('name', $fields, true), $this->name),
.......
]
It works fine, but I think it is complicated (and also not "elegant"). Is it possible to simplify that?
use Illuminate\Support\Arr;
class SchoolResource extends JsonResource
{
public function toArray($request)
{
$fields = $request->has('fields') ? explode(',', $request->fields) : [];
return Arr::only($this->resource->toArray(), $fields);
}
}
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';
I worked on this for a day. I get this same problem, but I don't understand.
<?php
class Users extends CI_Controller
{
function index()
{
redirect('Users/login');
}
function login()
{
$data['title'] = 'Selamat datang di Sistem Informasi Koperasi';
$data['main_content'] = 'login';
$this->load->view('Users/template', $data);
}
function logout()
{
$this->session->sess_destroy();
$this->session->set_flashdata('info_login', 'Anda sudah keluar dari sistem');
redirect('Users/login');
}
function validate()
{
//Load User Model
$this->load->model('Users_Model');
//Validate User
$query = $this->Users_Model->validate();
if($query != '') {
//Mengambil Roles dari Groups
$roles = $this->Users_Model->roles($query->group_id);
//$this->login_model->last_login($query);
$data = array(
'username' => $query->username,
'roles' => $roles,
'is_logged_in' => true
);
$this->session->set_userdata($data);
if($roles == 'administrators') {
redirect('Administrators/index');
} elseif($roles == 'managers') {
redirect('Managers/index');
}
else {
$this->session->set_flashdata('info_login', 'Mohon maaf anda belum terdaftar sebagai Group! Silahkan hubungi admin!');
redirect('Users/login');
}
} else {
$this->session->set_flashdata('info_login', 'Maaf,username dan password yang anda masukkan salah,silahkan coba kembali!');
redirect('Users/login');
}
}
}
In Chrome and Firefox I get this message. What should i do?
This webpage has a redirect loop The webpage at
http://localhost/simpks/index.php/Users/login has resulted in too
many redirects. Clearing your cookies for this site or allowing
third-party cookies may fix the problem. If not, it is possibly a
server configuration issue and not a problem with your computer. Here
are some suggestions: Reload this webpage later. Learn more about this
problem. Error 310 (net::ERR_TOO_MANY_REDIRECTS): There were too many
redirects.
this is my view template.php
<?php
$this->load->view('includes/header',$main_content);
$this->load->view('Users/'.$main_content);
$this->load->view('includes/footer');
?>
this is my model Users_Model.php
<?php
class Users_Model extends CI_Model{
function validate(){
$this->db->where('username',$this->input->post('username'));
$this->db->where('password',md5($this->input->post('password')));
$query = $this->db->get('Users');
if($query->num_rows == 1){
$row = $query->row();
return $row;
}
}
function roles($id){
$this->db->where('id',$id);
$query = $this->db->get('Groups');
if($query->num_rows == 1){
$row = $query->row();
return $row->name;
}
}
}
?>
use include instead loader if you call it in view.
ex : include 'includes/footer';
you don't have to put redirect('Users/login'); for session checking in your view class. Just erase it.
If you need redirect, put it in another page like users/test. If session is expired in users/test call redirect method in users/test controller. For better structure, i think you should minimize php function in view.
I am also facing that problem but both page's controllers i've redirects method so I add a refresh in redirect method, try it.
read at bottom of page CI redirect with refresh
<?php
class Users extends CI_Controller
{
function index()
{
redirect('another_controller/login');
}
}
Create another controller - another_controller.php
class another_controller extends CI_Controller
{
function login()
{
$this->load->view('home');
}
}