Error 404 despite that page exists Codeigniter - php

I have something like website.com/profile/nameofuser that is working.
But if I have website.com/profile/_nameofuser I get 404 error also website.com/profile/nameofuser_ or website.com/profile/nameof_user is working. It's not something related to accepted characters, but what's the problem?
class Profile extends CI_Controller {
public function __construct()
{
parent:: __construct();
$this->load->model('Profile_model');
$this->load->helper(array('url', 'form', 'htmlpurifier'));
}
public function index() {
$this->load->library('form_validation');
if(getUserData($this->uri->segment(2), "ID") < 0) {
$this->session->set_flashdata('error', 'Profil inexistent.');
redirect(base_url());
}
if (!is_cache_valid(md5('profile' . $this->uri->segment(2) . ''), 300)){
$this->db->cache_delete('profile', $this->uri->segment(2));
}
if(getUserData($this->uri->segment(2), "ID") > 0) {
/* some mysql queries.. */
}
$data["main_content"] = 'profile/profile_view';
$this->load->view('includes/template.php', $data);
} else {
$this->session->set_flashdata('error', 'Profil inexistent.');
redirect(base_url());
}
}
function _remap($method,$args)
{
if (method_exists($this, $method))
{
$this->$method($args);
}
else
{
$this->index($method,$args);
}
}
}
Here is my profile controller. I really don't know what's the problem. If I enter an invalid profile redirects with error flashdata so ti's ok. Maybe it's a remap problem?

1) Check the fie format in your view file.. if it is html file that mean you cannot call it without its format
for example
if your file is php format have name home-view.php
you can call it as
$this->load->view('home-view');
but if it is html file then the name in home-view.html
so you have to call it with its exstention as
$this->load->view('home-view.html');

your call to /profile/nameofuser is missing a fundamental from the MVC architecture.
You need to call a controller/method combination (in CI, your basic url is domain.com/controller/method)...
since you don't have a specific method for each user within the profile controller, which is actually a good thing, you need a method within the controller that handles your users. You already have it, it's called index
If you point your URL to /profile/index/nameofuser and change $this->uri->segment(2) to $this->uri->segment(3) you should get it to work
give it a try and let me know

Related

Is there any way to simplify this global authentication in codeigniter?

I'm trying to create a global authentication using _remap method in Codeigniter. Here are the website conditions for accessing the controller/method:
Method must be exist.
Some controllers can only be accessed if the user/admin have logged in.
Some controllers can only be accessed only by admin.
The _remap method is written in MY_Controller which will be inheritated to all the controller. Here is my code:
protected $must_login;
protected $must_admin;
public function _remap($method, $param = array())
{
# Check if method exist
if (method_exists($this, $method))
{
# Check whether the user has to be login to access it
if ($this->must_login)
{
# Check whether the user has logged in
if ($this->auth->is_loggedin())
{
# Check whether it has to be admin to access it
if ($this->must_admin)
{
# Check whether it is admin
if ($this->auth->is_admin())
{
# Run the method
return call_user_func_array(array($this, $method), $param);
}
else
{
# Redirecting to login form
$this->go('auth');
}
}
else
{
return call_user_func_array(array($this, $method), $param);
}
}
else
{
$this->go('auth');
}
}
else
{
return call_user_func_array(array($this, $method), $param);
}
}
else
{
$this->go('auth');
}
}
The code is working but i feel like it can be simplified. I have tried but it always end up in infinite redirect. Is there any way to simply this method?
Thank you in advance.
my preference is usually to put the check right in the constructor, and then return the user or admin with $this->
function __construct()
{
parent::__construct();
if (!$this->user = $this->users->returnUser())
{
redirect("userlogin");
}
}
Then $this->user is now available for everything that your controller calls - models and views:
echo 'Hello ' . $this->user->first_name . ' ' . $this->user->last_name ;
so then lets say you have Admins and a Superadmin. You don't have to check - does this admin have access to this controller? You can just use separate checks in each controller constructor:
if (!$this->admin = $this->admins->returnAdmin())
{
redirect("adminlogin");
}
// Or
if (!$this->superAdmin = $this->superadmins->returnSuperAdmin())
{
redirect("superadminlogin");
}
This also cleanly separates out where you are redirecting to so they can go to the correct login page. Finally it gives you a quick heads up when you are looking at the controller code - at the top of the page you will immediately know what kind of user should have access to it. Something to consider - would strongly encourage you not to check for login or admin status in your view files. Its much safer to create a few more view files. Your view files should not have the responsibility of determining whether someone is logged in or not. So basically once you have determined what the viewers status is in the constructor - thats it, you don't need to check again until the next controller call.

Redirect user to a self-made 404 page when users input wrong arguments

I'm using Codeigniter version 3.0.6 and now I have a controller named modifyfiles. The index function of this controller accepts an argument.
Using the given argument, the index controller will search a desired data in a model. The following code is my index function :
public function index($id){
$_SESSION['logged_in']['idmod'] = $id;
$this->data['modullist'] = $this->__getmodulbyid($id);
$this->data['lecturelist'] = $this->__getlecturelist();
if(count($this->data['modullist']) <= 0){
show_404();
} else {
$this->load->view($this->layout, $this->data);
}
}
It works very well for now, when I try to insert wrong number arguments it directs me to the codeigniter built-in 404 page.
But when I try to insert some non numbers arguments, say some characters, it directs me to my own 404 page.
Here's my routing rules :
$route['404_override'] = 'home/pagemissing';
$route['dosen/modifymodul'] = 'dosen-tools/modifymodul';
$route['dosen/modifymodul/(:num)'] = 'dosen-tools/modifymodul/index/$1';
I want when users input wrong arguments, no matter they were numbers or characters, the function will redirect to my own 404 page, not the built-in one. How can I achieve that?
I'm pretty sure the problem is in my conditional block
if(count($this->data['modullist']) <= 0){
show_404();
} else {
$this->load->view($this->layout, $this->data);
}
What should I write to replace the show_404() ?
Or if I'm not wrong, how can I replace the show_404() with an 404_override trigger?
Solved
I did a little research and ended up creating this callback in one of my routing rules
$route['dosen/modifymodul/(:num)'] =
function ($id){
if(is_numeric($id)){
return 'dosen-tools/modifymodul/index/'.$id;
} else {
return 'home/pagemissing';
}
};
Thanks everybody

CodeIgniter parameters - unable to load requested file

I have this controller:
class Work extends MY_Controller {
public function assign($id) {
//validation checks
if ($this->form_validation->run() === FALSE) {
$this->load->view("work/assign/" . $id);
} else {
//success
}
}
}
As well as a view at views/work/assign.php I also have the following route:
$route['work/assign/(:any)'] = 'work/assign/$1';
When I go to /work/assign/1 in my browser, and I get this error: Unable to load the requested file: work/assign/1.php I want it to render the page with the parameter 1
The loader doesn't care about your routes, and besides:
$route['work/assign/(:any)'] = 'work/assign/$1';
...doesn't do anything. This code:
$this->load->view("work/assign/" . $id);
...will always look for a file in APPPATH/views/work/assign/$id.php which I assume does not exist.
You want to use the second paramter in view() to load variables, for example:
$this->load->view("work/assign", array('id' => $id));
This will load the view file work/assign.php and import the variable $id.
The error you are getting is due to the wrong parameter in the view call
$this->load->view("work/assign/" . $id); since your last trailing slash tell CI that this is the .php and in your last trailing slash your $id=1 so it searches to load the 1.php the correct way to load the view and pass your id to view is make an array which contains the data you want to show in view then call view and pass the array, the array keys will converted to variables by CI
class Work extends MY_Controller {
public function assign($id) {
//validation checks
if ($this->form_validation->run() === FALSE) {
$data['id']=$id;
$this->load->view("work/assign" ,$data);
} else {
//success
}
}
}
In assign.php just echo $id and you will get desired id

SEO url gives 404-error in CodeIgniter

I am pretty new to codeigniter. I do know php.
How can I accomplish to load the right view?
My url: /blog/this-is-my-title
I’ve told the controller something like
if end($this->uri->segment_array()) does exist in DB then load this data into some view.
I am getting an 404-error everytime I access /blog/whatever
What am i seeing wrong?
unless you're using routing, the url /blog/this-is-my-title will always 404 because CI is looking for a method called this-is-my-title, which of course doesn't exist.
A quick fix is to put your post display code in to another function and edit the URLs to access posts from say: /blog/view/the-post-title
A route like:
$route['blog/(:any)'] = "blog/view/$1";
may also achieve what you want, if you want the URI to stay as just `/blog/this-is-my-title'
The may be more possibilities:
The most common - mod_rewrite is not active
.htaccess is not configured correctly (if u didn't edited it try /blog/index.php/whatever)
The controller does not exist or is placed in the wrong folder
Suggestion: if you only need to change data use another view in the same controller
if (something)
{
$this->load->view('whatever');
}
else
{
$this->load->view('somethingelse');
}
If none of those works post a sample of code and configuration of .htaccess and I'll take a look.
The best way to solve this problem is to remap the controller. That way, you can still use the same controller to do other things too.
No routing required!
enter code here
<?php
class Blog extends Controller {
function __construct()
{
parent::__construct();
}
public function _remap($method, $params = array())
{
if (method_exists($this, $method))
{
$this->$method();
}
else
{
$this->show_post();
}
}
function index()
{
// show blog front page
echo 'blog';
}
function edit()
{
// edit blog entry
}
function category()
{
// list entries for this category
}
function show_post()
{
$url_title = $this->uri->segment(2);
// get the post by the url_title
if(NO RESULTS)
{
show_404();
}
else
{
// show post
}
}
}
?>

How to replace "Login" button with user name in CodeIgniter

I'm trying to create a universal header for a website built on CodeIgniter, and I'm having trouble figuring out the code that will switch the 'Login' link for the user's name (with a link to the profile page) after the user logs in.
In the controller functions, I've tried the following code:
if(!$this->session->userdata($userSessionVar))
{
$data['header_output'] = "<li><a href='" . base_url() . "index.php/main/login'>Login</a></li>";
} else
{
$data['header_output'] = $this->session->data('userFirstName');
}
(I realize this is incomplete, based on my designs, but it's just to test.) $userSessionVar holds the value "logged in" once logged in. Probably not the best way to do that. And that doesn't seem to work (and I pass the $data to the view). I've also tried making a custom function:
function check_login()
{
$CI =& get_instance();
$userSessionVar = 'logged_in';
if( ! $CI->session->userdata($userSessionVar))
{
return false;
} return true;
}
And then use the true/false return to structure the $header_output variable. None of these seem to work. I'm new to CodeIgniter and have some intermediate level of PHP/HTML/CSS, etc. I'm sure I'm missing something obvious and would appreciate any help, as well as a heads-up on how to avoid including the code in every controller function.
The variable $userSessionVar is only available within the function check_login(), so when you try to use it outside of the function, it will be blank (and therefore useless).
I recommend that you simply use $this->session->userdata('logged_in') and $CI->session->userdata('logged_in') rather than using the variable $userSessionVar to store what appears to be a constant value.
Also, you have an error in your code. You need to replace $this->session->data('userFirstName') with $this->session->userdata('userFirstName')
Here's how I typically deal with user data. First, add auth.php to the models folder:
<?php
class Auth extends Model {
private $user_data = false;
function Auth() {
parent::Model();
if ($this->input->post('action') == 'login') $this->login();
else if ($auth_id = $this->session->userdata('auth_id')) {
$user = // load user data from the database into the variable $user
if ($user) {
$this->user_data = $user;
} else $this->session->unset_userdata('auth_id');
}
}
function login() {
// process POST, check with database, and then store user_id using
// $this->session->set_userdata('auth_id', $user_id_here)
}
function me() {
return $this->user_data? (object)$this->user_data : false;
}
}
?>
Then, auto-load the model. To do this, edit config/autoload.php like so:
$autoload['model'] = array('auth');
Now your IF statement could look like this:
if ($me = $this->me()) $data['header_output'] = $me->userFirstName;
else $data['header_output'] = '<li>Login</li>';
in your model auth.php you've got the statements
class Auth extends Model
and
parent::Model();
With CodeIgniter, should these not be "CI_Model"...?

Categories