I have created a web application with Codeigniter, and I have a problem at the url, controller and structure level.
I have the following web structure.
http://projectroot/admin
Then I have several sections like:
http://projectroot/admin/users
http://projectroot/admin/profile
http://projectroot/admin/section_tracking
http://projectroot/admin/section_products
etc...
I'm working with sessions and other libraries
Currently I have everything in a single controller called Admin, but I would like to create independent controllers that would be calling each part of the url.
In Admin I have:
class Admin extends CI_Controller {
public function __construct() {
parent::__construct();
$this->load->library('form_validation');
$this->load->library('My_PHPMailer');
$this->load->library('session');
}
public function index(){
if($this->session->userdata('login')){
if($this->session->userdata('urlnow')){
$url = $this->session->userdata('urlnow');
redirect($url);
}else{
redirect('admin/index');
}
}else{
$data = array();
$data['usererror'] = $this->session->flashdata('usererror');
$data['passerror'] = $this->session->flashdata('passerror');
$data['message'] = $this->session->flashdata('message');
$this->load->view('admin/index', $data);
}
}
...
public function users() {
code....
}
public function profile() {
code....
}
public function section_tracking() {
code....
}
public function section_products() {
code....
}
My idea is that the controller folder contains something like this:
admin.php
users.php
profile.php
section_products.php
section_visits.php
Creating independent Admin extends classes (user, profile, section_tracking and section_products) as independent controllers outside of admin, with a structure similar to this:
users.php
class Users extends Admin {
public function __construct() {
parent::__construct();
$this->load->library('form_validation');
$this->load->library('My_PHPMailer');
$this->load->library('session');
}
public function index(){
code here...
}
}
profile.php
class Profile extends Admin {
public function __construct() {
parent::__construct();
$this->load->library('form_validation');
$this->load->library('My_PHPMailer');
$this->load->library('session');
}
public function index(){
code here...
}
}
How can I do it? I don't want to use HMVC, I just want with MVC native.
Thank you
In your application/controllers/admin folder...Make following files
Admin.php
Users.php
Profile.php
Section_products.php
Section_visits.php
Then make call to each files like this...
http://projectroot/admin/users
http://projectroot/admin/profile
http://projectroot/admin/section_tracking
http://projectroot/admin/section_products
etc...
And here you want to extends admin controller.so make Admin_controller.php by extending CI_Controller in application/core. Your `Admin' controller must be like this....
class Admin_controller extends CI_Controller
{
function __construct()
{
parent::__construct();
}
}
Then always extends Admin_controller.CI_Controller automatically extended.
Related
I don't know if the title above is an correct title about my question.
Is there a way to declare a variable which we can access it from anywhere in view without need to redefine it again in each function in controller?
for example in controller file Students.php contains many function that handle the views, take a look below :
public function __construct() {
parent::__construct();
$data['count_student'] = $this->m_data->allStudent(); // count all students
}
public function index() {
$data['content'] = 'view-students';
$this->load->view('frontend/header' , $data);
}
public function showDetails() {
$data['content'] = 'view-detail-students';
$this->load->view('frontend/header' , $data);
}
I expected we can access $count_student in both view-students.php and view-detail-student.php without to define $data['count_student'] = $this->m_data->allStudent(); on each function that handle the view.
Is there possible ways to do that?
In the application/core/ create MY_Controller.php
<?php
class MY_Controller extends CI_Controller {
public function __construct() {
parent::__construct();
$this->load->model('m_data');
$this->data['count_student'] = $this->m_data->allStudent();
}
}
Controller use $this->data
class Students extends MY_Controller {
public function __construct() {
parent::__construct();
}
public function index() {
$this->data['content'] = 'view-students';
$this->load->view('frontend/header', $this->data);
}
public function showDetails() {
$this->data['content'] = 'view-detail-students';
$this->load->view('frontend/header', $this->data);
}
}
Now that you have extended the controller you shoudld be able to just go like
<?php echo $count_student;?>
On the view
I noticed that you can access variables in views without passing them if you declare them in the controller with $this->. Probably because they default to public visibility.
public function __construct() {
parent::__construct();
// $data['count_student'] = $this->m_data->allStudent(); // count all students
//
$this->count_all_the_students = $this->m_data->allStudents();
}
public function index() {
$data['content'] = 'view-students';
$this->load->view('frontend/header' , $data);
}
And then in the view you can use $this->count_all_the_students without putting it in the $data array.
<?php defined('BASEPATH') OR exit('No direct script access allowed'); ?>
<?php
echo 'I have misled ' . $this->count_all_the_students . ' students with my MVC breaking suggestions.';
If you are using the same variable in every controller function then you have to declare it as follows
class Example extends CI_Controller{
protected $data = array();
public function __construct() {
parent::__construct();
$this->data['count_student'] = $this->m_data->allStudent();
}
public function index() {
$this->data['content'] = 'view-students'; //variables are same
$this->load->view('frontend/header' , $this->data);
}
public function showDetails() {
$this->data['content'] = 'view-detail-students'; //variables are same
$this->load->view('frontend/header' , $this->data);
}
}
This applies only if you have common variables for all views in this controller.
If you are using different variables then use the following code.
class Example extends CI_Controller{
protected $count_student= "";
public function __construct() {
parent::__construct();
$this->count_student = $this->m_data->allStudent();
}
public function index() {
$data['content'] = 'view-students'; //Variable is different
$data['count_student'] = $this->count_students;
$this->load->view('frontend/header' , $data);
}
public function showDetails() {
$data['details'] = 'view-detail-students'; // Variable is different
$data['count_student'] = $this->count_students;
$this->load->view('frontend/header' , $data);
}
}
1.models/calists.php // My model file
Model file here i get the category list from database to the controller
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Catlists extends CI_Model
{
public function __construct()
{
$this->load->database(); //load database
}
public function getCategories()
{
$query = $this->db->get_where('category',array('status'=>'Enable'));
if ($query->num_rows() > 0)
{
return $query->result();
}
else
{
return array();
}
}
}
?>
2.controllers/catlist.php // controller file
Controller to get the data from model
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Catlist extends CI_Controller
{
public function __construct()
{
parent::__construct();
$this->load->model('catlists');
}
public function catlist()
{
$data['catlist'] = $this->catlists->getCategories();
$this->load->view('home', $data);
}
}
In header am printng the categories list
print_r($data['catlist']);
I am not sure what error you are getting here, but when you are loading model in controller, first letter should be capital.
$this->load->model('Catlists');
$data['catlist'] = $this->Catlists->getCategories();
In header you have to call
print_r($catlist);
The file name must match the class name.
For example
if your class is this:
class User_model extends CI_Model {
function __construct()
{
parent::__construct();
}
}
Your file will be this:
application/models/User_model.php
Here in you case your model name is
models/Calists.php
So your model file be
Model Calists.php
class Calists extends CI_Model {
function __construct()
{
parent::__construct();
}
public function getCategories()
{
$query = $this->db->get_where('category',array('status'=>'Enable'));
if ($query->num_rows() > 0)
{
return $query->result();
}
else
{
return array();
}
}
}
And you call this model file in you controller like this
Controller
public function __construct()
{
parent::__construct();
$this->load->model('calists');
}
CodeIgniter anatomy of model.
The following is a working example of how my Codeigniter website currently functions:
Model:
<?php
class Default_model extends CI_Model
{
function __construct()
{
// Call the Model constructor
parent::__construct();
}
function get_link()
{
$query = $this->db->query('SELECT * FROM links LIMIT 5');
return $query->result();
}
Controller:
<?php
class Home extends CI_Controller {
public function index()
{
$this->load->model('segment1/Page_model');
$data['link'] = $this->Page_model->get_link();
$this->load->view('page_view', $data);
}
}
View:
<h2>Link</h2>
<ul>
<?php if (isset($link)):?>
<?php foreach ($link as $row):?>
<li><?=$row->link?></li>
<?php endforeach;?>
<?php endif;?>
</ul>
I want to begin using a base controller for the above example, and while I've followed a few online examples - I can't quite get it right, and I'd appreciate some guidance...
I autoload the Model, no problem
The View file remains
I alter the config.php file
Controller:
<?php
class Home extends Main_Controller {
public function index()
{
$this->load->model('segment1/Page_model');
$this->load->view('page_view', $data);
}
}
MY_Controller
<?php
class MY_Controller extends CI_Controller
{
function __construct()
{
parent::__construct();
}
}
Now, here's where I get stuck - I can't quite figure out exactly what goes in the Main_Controller, and how it's structured...
Main_Controller:
<?php
class Main_Controller extends MY_Controller
{
function __construct()
{
parent::__construct();
//
// WHAT GOES IN HERE?
// SERIOUSLY, HELP!
//
}
}
Clearly, there's one big line of data missing from the original controller...
$data['link'] = $this->Page_model->get_link();
How does it all tie up?
Not exactly sure if I understand your question correctly, but if you want to avoid repeating this line:
$data['link'] = $this->Page_model->get_link();
What you can do is to put that in the constructor and create a public variable where you can store it.
i.e.
Main_Controller:
<?php
class Main_Controller extends MY_Controller
{
public $link;
function __construct()
{
parent::__construct();
$this->load->model('segment1/Page_model');
$this->link = $this->Page_model->get_link();
}
}
Controller:
<?php
class Home extends Main_Controller {
public function index()
{
$this->load->view('page_view', array('link' => $this->link));
}
public function another_page()
{
// you can keep using the value assigned to link in other
// methods without having to call Page_model->get_link() everytime
$this->load->view('page_view', array('link' => $this->link));
}
}
i'm using codeigniter for my project and i have this class model which i call Genesis which looks like this:
class Genesis_model extends CI_Model {
function __construct() {
parent::__construct();
}
function get() {
return 'human soul';
}
}
and i have another model, stored in the same directory, which extends Genesis_model
class Human_model extends Genesis_model {
function __construct() {
parent::__construct();
}
function get_human() {
return $this->get();
}
}
Human_model is used by Human controller
class Human extends CI_Controller {
function __construct(){
parent::__construct();
$this->load->model('human_model');
}
function get_human() {
$data['human'] = $this->human_model->get_human();
$this->load->view('human/human_interface', $data);
}
}
if i execute the code, it will produce an error which point to return $this->get(). it reads "Fatal error: Class 'Genesis_model' not found in ...\application\models\human_model.php on line 2".
i use this method because nearly all my models shared almost identical structure. I gather the similar functionality in Genesis while the other models serve only as data suppliers unique to the tables they represent. it works well in my asp.net (vb.net) but i don't how to do it in codeigniter.
is there a way for Human_model to inherit Genesis_model. i don't think i'm allowed to use include('genesis_model.php'). i don't know if it works either.
thanks in advance.
core/MY_Model is good if there's only 1 important superclass for your models.
If you want to inherit from more than model superclass, a better option is to change your autoload configuration.
In application/config/autoload.php, add this line:
$autoload['model'] = array('genesis_model');
Put the file genesis_model.php in the core directory
Change your Human_model to this:
include('genesis_model.php');
class Human_model extends Genesis_model {
function __construct() {
parent::__construct();
}
function get_human() {
return parent::get();
}
}
notice the get_human function and the include.
You have to include the Genesis_model on your Human_model.php like this:
include_once( APPPATH . 'folder/file' . EXT );
Or you can autoload it on your config/autoload.php file, what I think is stupid =)
other solution
<?php
$obj = &get_instance();
$obj->load->model('parentModel');
class childModel extends parentModel{
public function __construct(){
parent::__construct();
}
public function get(){
return 'child';
}
}
?>
//My controller section
<?php
class Myadmin extends CI_Controller
{
public function _construct()
{
parent::_construct();
$this->load->library('form_validation');
$this->load->helper('form');
$this->load->model('adder','',TRUE);
}
public function index()
{
echo " i am about to call the model";
$this->adder->insert_user();
}
}
?>
**//My model section**
<?php
class Adder extends CI_Model {
function_construct() {
parent::_construct();
}
public function insert_user()
{
echo " Hi ,the model is accessed";
}
}
?>
Is it because of "function_construct()"?
It has no space and you should use two _
function _construct(){
parent::_construct();
}
Same in Controller
The problem is the way you load the model in your controller.
In the current version of the CodeIgniter you should do something like this:
//loading the model
$this->load->model('adder', 'fubar');
//accessing it's functions
$this->fubar->function();
for more info see this.
EDIT:
You have defined a _construct() function which must be __construct().
Also you should fix parent::_construct(); to parent::__construct().