Can't access a Codeigniter controller in sub folder - php

I have set up a folder with a controller in it: controllers/admin/home.php, but I get a 404 from the browser when I try to access it.
This is my routes file:
$route['employers'] = "employers/home";
//$route['employers/dash'] = "employers/dash";
$route['default_controller'] = "home";
$route['404_override'] = '';
This is the controller file:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class home extends CI_Controller {
function __construct(){
parent::__construct();
/*
enable profiler
*/
//$this->output->enable_profiler(TRUE);
$this->load->helper('url');
$this->load->library('ion_auth');
$this->load->library('session');
$this->load->library('form_validation');
$this->load->helper('layout');
}
}
.htaccess seems fine standard. Any ideas on what i'm doing wrong?

Note some things:
1) Routes are executed in the order they're written, and your custom routes MUST follow the default ones. So, it should be:
$route['default_controller'] = "home";
$route['404_override'] = '';
$route['employers'] = "employers/home";
This if your controller "home" is inside the folder "employers".
2) Controllers don't need all that stuff you wrote, indeed you don't even need to call the parent constructor unless you're planning to load libraries and resource for the whole controller's methods (which can be achieve also by autoloading them in the autoload.php file), so it could simply be:
file: application/controllers/employers/home.php
class Home extends CI_Controller {
function index()
{
// this is the method you're calling with your URL!
}
}
3) As per above, and as already pointed out by #Wesley, with your url you're trying to access the INDEX method of your controller HOME in your subfolder EMPLOYERS. But you didn't defined an index() method (which is the one called by default if no other is supplied).
It seems, instead, that CI is trying to look for an employers controller and a home method; if it doesnt find it, but you have a employers folder, it tries to access the index method in the home controller in the employers folder. And, since it didn't find it either, you're getting the 404 page.
Hope I'm clear, otherwise just ask.

You failed to say how you were trying to access it via url. It should be:
{YOUR_BASE_URL}admin/home
... followed by optional URL segments (/method/param1/param2/etc).
Without the additional segments, this would by default load the index method. However, since you don't have any methods defined, there's nothing to load.
If this still fails after you define a method, move the controller file out of the sub-directory for starters, and make sure it works.

Related

Called controller can't access anything

in codeigniter I have my main controller:
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Main extends CI_Controller
{
public function index()
{
$this->load->library('../controllers/forum');
$obj = new $this->forum();
$obj->test();
}
}
And the controller I'm trying to access:
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Forum extends CI_Controller
{
function __construct()
{
echo "testing1";
$this->load->library('session');
parent::__construct();
$this->load->database();
$this->load->model('model_forum');
}
public function index(){
}
public function test(){
echo "testing2";
$this->data['forums'] = $this->model_forum->getForums();
$this->load->view('homepage', $this->data);
}
}
Everything is fine with my model_forum.php file, because it works if I put all the code in Main controller. But if I'm trying to access Forum controller, nothing works, only "testing1" echo goes through. Picture of error:
Anyone has any idea what I'm doing wrong? I'm new to PHP and codeigniter so I'm struggling a little bit. Thanks in advance.
You can't load a controller from a controller in CI - unless you use HMVC or something.
You should think about your architecture a bit. If you need to call a controller method from another controller, then you should probably abstract that code out to a helper or library and call it from both controllers.
UPDATE
After reading your question again, I realize that your end goal is not necessarily HMVC, but URI manipulation. Correct me if I'm wrong, but it seems like you're trying to accomplish URLs with the first section being the method name and leave out the controller name altogether.
If this is the case, you'd get a cleaner solution by getting creative with your routes.
For a really basic example, say you have two controllers, controller1 and controller2. Controller1 has a method method_1 - and controller2 has a method method_2.
You can set up routes like this:
$route['method_1'] = "controller1/method_1";
$route['method_2'] = "controller2/method_2";
Then, you can call method 1 with a URL like http://example.com/method_1 and method 2 with http://example.com/method_2.
Albeit, this is a hard-coded, very basic, example - but it could get you to where you need to be if all you need to do is remove the controller from the URL.
You could also go with remapping your controllers.
From the docs: "If your controller contains a function named _remap(), it will always get called regardless of what your URI contains.":
public function _remap($method)
{
if ($method == 'some_method')
{
$this->$method();
}
else
{
$this->default_method();
}
}

Using custom named controllers with codeigniter

Hi I'm working on a application that uses a admin environment and a user environment. To make my code and controllers more readable I would like to use some kind of a prefix for my admin and user controllers. Or maybe use a different directory for the admin en user controllers. Without using the exact name in the url to call the controllers.
Does anybody know if there is a way to do this or a work around for my idea.
For example I would like to use: user.[controllername].php or user_[controllername].php
EDIT:
So when I use routes to separate the user controllers from the admin controllers, it brakes my template resolver.
For instance lets say the url is: http://myapplication.com/user/profile in normal cases this would call the user controller and the function profile. My template resolver looks for the folder user and checks if there is a level1.tpl file.
Lets say we want to edit this profile the url would be: http://myapplication.com/user/profile/edit/1 now it would search in the folder user for a level2.tpl file and would call the function edit with id 1.
The problem with the routes is that it prepends something to the url witch I don't want because then it searches in the wrong folder for instance when we use admin/dashboard it will look in the folder admin instead of the folder dashboard.
So basically what I only need is only to tell the application to use a different directory where the controllers are located or a different filename base on what kind of user is logged in.
Thanks in advance, for sharing you knowledge.
You can do that in many ways.
1. Create two file in application/core named "Admin_Controller.php" and "User_Controller.php" with following class signature,
class Admin_Controller extends CI_Controller
{
public function __construct()
{
parent::__construct();
}
}
and
class User_Controller extends CI_Controller
{
public function __construct()
{
parent::__construct();
}
}
In these classes you can do use your PHP logic to do whatever you wants, just simply extends your Controllers to Admin_Controller or User_Controller.
eg: class Home extends User_Controller {} or class Dashboard extends Admin_Controller {}
2. You can also simply do that with routes.php
eg:
// for admin
$route['admin/(.+)'] = 'admin_$1';
// for frontend
$route['(.+)'] = 'user_$1';
I hope this might give you some idea.

Codeigniter 3 - Make URLs case insensitive

With CI3 released controllers must now be Ucword-style (for whatever reason). No problem changing these, but upgrading any site now leads to 404s wherever it's applicable (which is pretty much everywhere).
Is there a way to make it so the old URLs still work (in addition)? Ie I have a controller 'Admin.php" the index() fn of which used to be called
http://example.com/admin
now it must be called
http://example.com/Admin
Is there a way to have both work (on CentOS). Maybe via Apache rewrite and/or config?
You can set your routes in :
application/config/routes.php
$route['admin'] = 'admin/index';
You can set your Controller as following code in controller.
application/controllers/Admin.php
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Admin extends CI_Controller {
public function __construct() {
parent::__construct();
$this->load->model(array('admin_model'));
}
public function index()
{
$this->template->view('admin/index');
}
}
?>
If case insensitive routes are required, do below changes to URI.php
Location of File: system/core/URI.php
Find $this->_parse_request_uri() and replace it with strtolower($this->_parse_request_uri())

Separating Controllers for each module in Code Igniter

P.S This question may already be existing but the answer didn't satisfied what I was trying to figure out. I'm using code igniter for the first time in my new project.
So I have this only one controller which is main.php and populated with a lot of public function. Now everytime I go to main.php the url is looks like cmms/main and everytime I'm going for its subclass it goes cmms/main/asset.
Now the subclass asset has many functions which are in main.php. What I want is to make separate controllers for each module. so i have cmms/main as main.php & cmms/asset as asset.php instead of making it under cmms/main/asset. Would this be possible? or I should just leave it alone and continue putting all codes in the main.php controller?
My default route is the main controller.
$route['default_controller'] = 'main';
You have two ways to do that.
Keep one controller but URL is different. (Method 01)
Keep new controller for each new function. (Method 02)
(these topics describe below)
Method 01
go to - config/routes.php, and add new routes like this
$route['cmms/asset'] = 'cmms/main/asset';
$route['cmms/contact'] = 'cmms/main/contact';
So in view you should call anchor tags like this
Assets
Contact Us
Method 02
Create new controller for each new methods.
File name - main.php
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class Main extends CI_Controller {
}
File name - asset.php
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class Asset extends CI_Controller {
}
File name - contact.php
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class Contact extends CI_Controller {
}
So in view you should call anchor tags like this
Assets
Contact Us
you can create Modules for your class in following ways,
By creating separate class under your application controllers directory eg: main.php, assets.php here your URL will be cmms/main or cmms/asset
Creating sub folders under your application controllers directory and create controller classes under it main/main.php, asset/asset.php here URL will be cmms/main/main, cmms/asset/asset, if you want just cmms/main or cmms/asset in URL than you need to create routes in route.php file.
This way you can make codeigniter Modular in this way every module will have separate controller, model and view even libraries in its own module directory and URL will be same as cmms/main or cmms/asset for each controller. you need to install wiredesignz's HMVC extension here is URL you can download https://bitbucket.org/wiredesignz/codeigniter-modular-extensions-hmvc/overview
important please read documentation for HMVC extension to use it.
it seems that you are having trouble to write long url each and every time....
So,better way is to use routes for ease.
For Ex: $route['login'] = "main/login";
Now if you use login directly in url it will call main class and it's login method
using routes you can prevent exposing your controller name and also for shorten URl

codeigniter controller index function call requires its name

I have a Controller named Categories and one function in it called index with 1 parameter $cat_id
so it looks like this:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class categories extends CI_Controller {
function __construct(){
parent::__construct();
}
public function index($cat_id = null){
}
}
the problem comes when i call it from the browser... i use this:
http://www.mysite.dev/categories/12311323
but returns 404 error page
instead if i use
http://www.mysite.dev/categories/index/12313131
will work fine...
how can i make sure it wont need index in the URL for the index function?
The default CodeIgniter routing is /controller/function/argument. In order to specify an argument, you need to first specify the function. If you want to specify an argument without the function, you need to define a custom route. Adding this line to your route configuration file should do what you want.
$route['categories/(:num)'] = "categories/index/$1";
What you describe are the default (pre-configured) routes of CI. You can define your own to make the pattern you describe in your question work. See: URI Routing

Categories