codeigniter-base-controller is an extended BaseController
class to use in your CodeIgniter applications. Any controllers that inherit from BaseController
or AdminController
get intelligent view autoloading and layout support. It's strongly driven by the ideals of convention over configuration, favouring simplicity and consistency over configuration and complexity.
<?php namespace App\Controllers\Admin;
use App\Models\ArticleModel;
class Articles extends AdminController
{
public function __construct()
{
$this->article = model('App\Models\ArticleModel');
$this->model_class = 'article';
}
/**
* List Articles
*/
public function index()
{
$this->data['articles'] = $this->article->findAll();
}
/**
* Create Article
*/
public function create()
{
return $this->adminCreate($this->request->getPost());
}
/**
* Update a Article
* @param int $id The article id
*/
public function update($id)
{
return $this->adminUpdate($id, $this->request->getPost());
}
/**
* Delete Article
* @param int $id The article id
*/
public function delete($id = null)
{
return $this->adminDelete($id);
}
}
Drag the AdminController.php file into your app/Controllers/Admin/ folder. This way, you have a distinct difference bettwen your backend and front-end. All your controller inside this folder should extend to adminController and your controllers outside this folder should extend to baseController. This way, only your backend controllers will have access to your CRUD functions.
This way you should run the following command in your terminal.
composer require marcogmonteiro/ci-admin-controller
Or add the following to your composer.json file.
{
"require": {
"marcogmonteiro/ci-admin-controller": "dev-master"
}
}
If you install the package via composer then controllers shoulse use a different namespace. In that case your controllers that extend to base Controller should extend to \MyController\Controllers\MyController and the ones that will use the adminController should use \MyController\Controllers\Admin\AdminController, like so:
<?php namespace App\Controllers;
class Home extends \MyController\Controllers\MyController
{
/**
* No view loading here!
*/
public function index()
{
}
}
Views will be loaded automatically based on the current controller and action name. Any variables set in $this->data
will be passed through to the view and the layout. By default, the class will look for the view in app/views/controller/action.php.
In order to prevent the view being automatically rendered, set $this->view
to false
.
$this->view = false;
Or, to load a different view than the automatically guessed view:
$this->view = 'some_path/some_view.php';
Views will be loaded into a layout. The class will look for an app/views/layouts/backend.php layout file or app/views/layouts/application.php depending if it's the baseController or the adminController.
In case you want to override this in your controller just set your layout to whatever you want.
$this->layout = 'layouts/yourlayout.php'
In order to specify where in your layout you'd like to output the view, the rendered view will be stored in a $yield
variable:
<h1>Header</h1>
<div id="page">
<?php echo $this->renderSection('yield') ?>
</div>
<p>Footer</p>
If you wish to disable the layout entirely and only display the view - a technique especially useful for AJAX requests - you can set $this->layout
to FALSE
.
$this->layout = FALSE;
Like with $this->view
, $this->layout
can also be used to specify an unconventional layout file:
$this->layout = 'layouts/mobile.php';
Any variables set in $this->data
will be passed through to both the view and the layout files.
Your views should be created to support the built in functionality of layouts that comes with codeigniter 4
<?php echo $this->extend($layout); ?>
<?php echo $this->section('yield') ?>
<h1>Hello World from the home/index view!</h1>
<?php echo $this->endSection() ?>
As for your layouts, those should have a render section called yield.
<!doctype html>
<html>
<head>
<title>My Layout</title>
</head>
<body>
This is my layout content
<?php echo $this->renderSection('yield') ?>
</body>
</html>
To actually be able to rendere a view directly without the layout we need an empty layout doing the render. For that there's a nolayout.php file included in your Views/layouts folder that only does the view render.
<?php echo $this->renderSection('yield') ?>
The complete folder structure is now included in the project.
If you want to load helpers in your controllers in a global scope and not inside a function all your have to do is declare the helpers property as array with all your helpers, like so:
<?php namespace App\Controllers;
class Home extends AdminController
{
protected $helpers = ['url'];
public function index()
{
}
}
There's a few functions that you can use in your adminController that are not avaiable in your baseController. To do that some rules must be followed. First you need to load the main model your controller will be working with. Let's say you have a Articles controller and a ArticleModel first you load your model.
$this->article = model('App\Models\ArticleModel');
As you can see I'm loading the model into a class property called article. In this case my $model_class property should also be called article.
$this->model_class = 'article';
This way if your Article controller needs access to a update functionallity all you need to do is create a update function like so:
public function update($id)
{
return $this->adminUpdate($id, $this->request->getPost());
}
This update function should always return the update result that was set on your adminController function.
In case you want to send the admin_update method something else other than your post data you can do it just like this:
public function update($id)
{
$data = $this->request->getPost();
$data['my_new_field'] = 'foobar';
return $this->adminUpdate($id, $this->request->getPost());
}
This is specially usefull if you want to add some extra data that was not given by the post.
By default the success action of this function will always redirect to your index function in your controller. Using this structure always assume that you have a index function.
This redirect will also set a confirm flashdata automatically that can be used in your views.
In case you need to override this behavior that can be done by returning a diferent result.
public function update($id)
{
$this->adminUpdate($id, $this->request->getPost());
return [
'url' => '/admin/list_articles',
'success' => 'Your article was updated.'
];
}
This way you're redirecting the user to your /admin/list_articles with the flashdata "your article was updated.".
In case you want to use AdminController in root directory, or any other directory change the $directory property.
protected $directory = ''; // Set default directory
The CRUD methods now support the use of language variables. Those should be se in your app/languages folder depending on your locales settings. For now the following languages are supported:
- English
- Portuguese
In your adminController.php there's a custom helper being loaded called error helper. That should be placed in your helpers folder and it's only purpose is to serve as a shortcut for the 404 exception.
// This is just the same thing
show_404();
// as
throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound();
You can now use this on your controllers too everytime you need to show a 404 error. Since its autoloaded on your adminController.
- Add better error messages based the class name, so we can say something like "Your article was update" instead of item;
If you're still using codeigniter 3 and want something like this that can be found here: jamierumbelow/codeigniter-base-controller