CodeIgniter 4 how to load a model in the controller? - php

First of all, I am having very little knowledge of CodeIgniter 3 and now I am first time using the new CodeIgniter 4. For the HMVC module building, I was using MX_Controller in CI3. Now when I came to know the CI4 is by default supporting HMVC I am trying to make use of it. When I try to port my first module I am getting an error in the Controller about the constructor.
How can I load my model in this controller?
Can't I load my model in the constructor straight away?
Template.php [Controller]
<?php
namespace Modules\Template\Controllers; // sPiDeR adder namespace for CI4 support
//defined('BASEPATH') OR exit('No direct script access allowed');
class Template extends \CodeIgniter\Controller { // Using CI controller instead of MX Controller
public function __construct()
{
parent::__construct();
$this->load->model(array(
'template_model'
));
}
public function layout($data)
{
$id = $this->session->userdata('id');
$data['notifications'] = $this->template_model->notifications($id);
$data['quick_messages'] = $this->template_model->messages($id);
$data['setting'] = $this->template_model->setting();
$this->load->view('layout', $data);
//echo view('layout', $data); //sPiDeR update syntax change
}
public function login($data)
{
$data['setting'] = $this->template_model->setting();
$this->load->view('login', $data);
//echo view('login', $data); //sPiDeR update syntax change
}
}
Error I am getting in Debugger

Please use model like that its working surely.
use App\Models\Model1;
use App\Models\Model2;
class Myclass extends Backendcontroller
{
public function __construct()
{
$this->Model1 = new Model1();
$this->Model2 = new Model2();
}
$foo = $this->Model3->where('bar', $bar)->findAll();

I'll recommend using Upgrading from 3.x to 4.x guide while you migrate your app from CI3 to CI4. All the changes you might require to convert your app from version 3 to 4 are explained in it.
Steps for upgrading models include what you need. Quoting only part relevant to question:
Instead of CI3’s $this->load->model(x);, you would now use $this->x = new X();, following namespaced conventions for your component. Alternatively, you can use the model function: $this->x = model('X');.
You can load models from within the constructor if you follow one of these approaches.

Related

Trait in CodeIgniter

I'm trying to use traits in CodeIgniter. I put the Trait in the libraries directory and then loaded the library in the controller. Then I used the trait in the model, but it didn't work and I received the following error
Trait file (in library):
trait DataTablesTrait{
public function query(){
$this->db->select('*');
$this->db->limit(10, 1);
return $this->db->get('my_table');
}
}
?>
Controller:
class myController extends CI_Controller {
public function __construct(){
parent::__construct();
$this->load->library('DataTablesTrait');
$this->load->model('ABC_Model');
}
}
Model:
class ABC_Model extends CI_Model {
use DataTablesTrait;
function callQuery(){
$this->query();
}
}
I got this error:
Non-existent class: DataTablesTrait
Please advise
CodeIgniter (CI) isn't trait or namespace friendly but they can be used. It requires working around CI a bit though.
The main problem, the CI thing you have to work around, is the call
$this->load->library('DataTablesTrait');
CI will find this file but load->library will try to instantiate the trait which fails because it is not possible to instantiate a Trait on its own.
Replace the line above with
include APPPATH.'/libraries/DataTablesTrait.php';
You should be free of the error with that. But you're not going to get results because callQuery() does not return anything. To round out the test have callQuery() return the CI_DB_result object the Trait should produce
public function callQuery()
{
return $this->query();
}
Add an index function to the controller so we can dump the output
public function index()
{
$DB_result = $this->ABC_Model->callQuery();
var_dump($DB_result->result());
}
This should produce the expected output - assuming that 'my_table' has data :)
Worth saying that traits are now fully supported in Codeigniter 4 and can be implemented as you would expect using namespaces etc.
// TRAIT
namespace App\Controllers\traits;
trait YourTraitName {
}
// CONTROLLER
use App\Controllers\traits\YourTraitName;
class Admin extends BaseController {
use YourTraitName;

Codeigniter and Mongodb library - do I need a model?

I am trying my hand out with mongodb as a backend to my codeigniter application.
I found and followed this example: http://www.surfinme.com/codeigniter-mongodb/
So I have the following structure:
+application\
libraries\
Mongo_db.php
config\
mongodb.php
controllers\
api.php
This is what my api.php file looks like so far:
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Api extends CI_Controller {
public function __construct()
{
parent::__construct();
//loading the mongodb library
$this->load->library('mongo_db');
}
public function index()
{
$data['main_content'] = "dashboard";
$this->load->view('includes/template',$data);
}
public function list_available()
{
//connect to mongodb collection (i.e., table) named as ‘surfinme_index’
$collection = $this->mongo_db->db->selectCollection('testcollection');
$result=$collection->find();
foreach($result as $data)
{
var_dump($data);
}
}
}
And the code seems to be working. It gets my data out of the database and dumps it to my browser. But this "feels" wrong becuase I don't have a model.
Or should I be viewing the library as my model layer?
I could just as easily create a file in the models folder called api_model and make the calls to the library from there.
But is that overkill?
Any comments would be appreciated.
Thanks.
Depends on how tightly you want to adhere to MVC principals.
By creating a model for database operations you get several potential benefits. First, it provides a source that can be reused by multiple controllers. For example, there may be more than one controller that uses selectCollection. Second, if for some reason you decide to change databases you only have to modify the Models as opposed to every controller that makes calls to mongo_db.

Common functions in CodeIgniter

I am new to CodeIgniter.
I am using HMVC in CodeIgniter and want to use a module function in many other modules:
e.g I have a Locaton_model with function get_locations($param) { return; }
How do I use the above function in many other modules? Should I load the model in other module controllers every time I need this function or define the function some where globally?
You can easily achieve that by using core controllers:
http://ellislab.com/codeigniter/user-guide/general/core_classes.html
Instead of beginning your model with:
class Some_model extends CI_Model {}
You start with:
class Some_model extends MY_Model {}
Edit:
It is also possible to use libraries:
http://ellislab.com/codeigniter/user-guide/general/creating_libraries.html
This is useful when you want more general things, like a search engine, a IMAP interface, that kind of stuff.
if your creating your own model first make sure it is inside the core folder second on your controller extends the model name like this
class myController extends Locaton_model
{
function index()
{
$this->load->model->("your model name");
$this->yourmodelname->functionname($param);
}
}

Creating a filter from parent class?

I'm using CodeIgniter and I want to create some sort of filter to know when a user may/may not access a current controller
If anyone has any idea how to implement this in a different manner, great, but what I was thinking (and trying to do) is the following:
CI_Controller - which is the basic CodeIgniter controller class
MY_Controller - the basic controller which I use which extends CI_Controller
[Controller] - any "physical" controller
what i've tried to do is:
MY_Controller.php
class MY_Controller extends CI_Controller{
private static $namespace = null;
private static $permission = array('site', 'settings');
public function __construct(){
if ((!isset($_SESSION['user'])) && (in_array(__CLASS__, $permission))){
throw new Exception('Unauthorized');
}
parent::__construct();
}
}
obviously, this doesn't work as CLASS will always be that of MY_Controller and not that of the child object... and NAMESPACE doesn't work aswell.
Anyone has any idea? because Id really hate to start putting this snippet of code in every other class, and I'll prolly need the filtering later for some more elaborate things...
As there's no answer so far, maybe this suggestion might help. It's a different approach, though, that uses the Modular Extensions - HMVC ...
Like this you can have a module "login" with a controller that holds some methods to log a user in, to check session status and to log a user out (and the like).
In each other module you can now load the module login and check for the status and redirect if needed ...
There's a tutorial HMVC: an Introduction and Application I followed on nettuts that shows how to do the CodeIgniter From Scratch: Day 6 – Login in that way. Maybe that helps. I had some difficulties as it's with an old codeigniter version. So maybe this thread helps.
It's not how you're trying to do things, but maybe it helps!
I did not try it but what I saw in this forum might be working for you. The predicted code is:
class MY_Controller extends Controller{
private static $permission = array('site', 'settings');
public function __construct(){
if ((!isset($_SESSION['user'])) && (in_array(__CLASS__, $permission))){
throw new Exception('Unauthorized');
}
parent::Controller();
}
}
But then you'd need to use
class My_controller extends MY_Controller
instead of
class My_controller extends Controller
I solved it in the following manner... simply in the constructor, I defined the current class
class MY_Controller extends CI_Controller{
private static $permission = array('site', 'settings');
public function __construct($currentController = __CLASS__){
if ((!isset($_SESSION['user'])) && (in_array($currentController , $permission))){
throw new Exception('Unauthorized');
}
parent::Controller();
}
}
when calling the physical controller, we simply write as follows
class PhysicalController extends MY_Controller{
public function __construct(){
parent::__construct(__CLASS__);
}
}

codeigniter 2.02 - passing argument - page not found

i use ubuntu 10.10 and codeigniter 2.0.2
i have successfully installed CI by opening welcome index page
later on i was following tutorial and have added new controller to my project:
class Start extends CI_Controller{
var $base;
var $css;
function __construct() {
parent::__construct();
$this->base=$this->config->item('base_url');
$this->css=$this->config->item('css');
}
function hello($name){
$data['css'] = $this->css;
$data['base'] = $this->base;
$data['mytitle'] = 'Welcome to this site';
$data['mytext'] = "Hello, $name, now we're getting dynamic!";
$this->load->view('testview', $data);
}
}
as well as view(testview.php) and css variable in question. then upon trying to test it by executing http://localhost/ci/index.php/index/start/hello/fred i get 404 page not found.
thank you
use this class declaration instead
class Start extends CI_Controller{
and instead of your php4 constructor
use this instead of Start()
function __construct(){
parent::__construct();
$this->base=$this->config->item('base_url');
$this->css=$this->config->item('css');
}
The actual reason you're getting a 404 is because you're telling it to find a function called fred. The url you're probably meaning to hit is this...
http://localhost/ci/index.php/start/hello/fred
Since 2.0.x , Codeigniter has changed their base controller class names and moved everything to php5 style constructors, among other things.
You are probably following a older tutorial.
It seems you have used an old tutorial. In CodeIgniter 2, some things are different.
extend CI_Controller instead of extend Controller
Use __construct for constructors instead of the class name.
function __construct(){
parent::__construct();
// More stuff
}
The url should be http://localhost/ci/index.php/start/hello/fred. CodeIgniter's URLs are used like so:
http://localhost/ci/index.php/<controller>/<method>/<params>

Categories