CodeIgniter reUse/extend controller - php

I have my controller
class Page extends CI_Controller {
public function id() {
$this->load->model('content');
$page = $this->uri->segment(3, 0);
if($page == 0)
$page = $this->content->get_default_page($page);
$data['navigation'] = $this->content->getNav();
$data['pagename'] = $this->content->get_pagename($page);
$data['content'] = $this->content->get_content($page);
$this->load->view('main', $data);
}
}
Now I'll try to explain.
Im getting navigation, and navigation text from mysql (id, navName, navText).
then im returning those elements in views/main_view.php in url like: http://abc.com/page/id/1 etc...
Now i need to create other controller like mySuperDuperModule which have some functions not just text.
The problem is that if i create new controller like Gallery(), i need to copy all the stuff from Page() controller to make website show the same.
Is there any way not to do that ?

You can create base controller under /application/core/MY_Controller.php
Here MY_ is the value specified for $config['subclass_prefix'] in /application/config/config.php
class MY_Controller extends CI_Controller
{
protected $data;
public function __construct()
{
parent::__construct();
$this->data = array();
}
public function loadPage($page)
{
$this->load->model('content');
if($page == 0)
$page = $this->content->get_default_page(); // I hope this function will give default page from database table. (A Change from your code)
$this->data['navigation'] = $this->content->getNav();
$this->data['pagename'] = $this->content->get_pagename($page);
$this->data['content'] = $this->content->get_content($page);
}
}
Your modified Page Class in /application/controllers/page.php
class Page extends MY_Controller
{
public function __construct()
{
parent::__construct();
}
public function id()
{
$page = $this->uri->segment(3, 0);
parent::loadPage($page);
$this->load->view('main', $this->data);
}
}
and your new gallery controller can be in /application/controllers/gallery.php
class Gallery extends MY_Controller
{
public function __construct()
{
parent::__construct();
}
public function id()
{
$page = 10; // Assuming gallery page index is 10 in database table OR you can change any logic here.
parent::loadPage($page);
$this->load->view('main', $this->data);
}
}
you can create as many controllers as you want by extending MY_Controller.

You can pass these two lines to any controller
and they will display the same template.
$data['navigation'] = $this->content->getNav();
$data['pagename'] = $this->content->get_pagename($page);
If you still dont understand try to use this library
https://github.com/philsturgeon/codeigniter-template

Related

CodeIgniter: $data access in all views

I need to access $data[] variables in whole site, in all views. I created TestLeangue controller and assign some values to $data but in all views say that variable is not defined
class TestLanguage extends MY_Controller
{
public function __construct() {
parent::__construct();
$this->lang->load("menu","english");
}
function index() {
$data['shipping'] = $this->lang->line('menu_shipping');
$this->load->view('templates/navigation', $data);
}
}
I echo and say that I have undefined variable.
<?= $shipping; ?>
Why don't you use that data like a global variable?
class MY_Controller extends ...
{
protected $data = [];
}
Then everytime when you extend your custom controller you will have access to the general data.
class MyCustomStackOverflowController extends MY_Controller
{
public function index()
{
$this->load->view('index', $this->data);
}
}
Also, you can use $this->data to load it with general information for current controller like:
class MyCustomStackOverflowController extends MY_Controller
{
public function __construct()
{
parent::__construct();
$this->data['title'] = 'Stackoverflow';
}
public function index()
{
...
}
}
Use Index of $data as a variable name ($shipping), to get the value that you have assigned as $data['shipping']
Controller
class TestLanguage extends MY_Controller
{
public function __construct() {
parent::__construct();
$this->lang->load("menu","english");
}
function index() {
$data['shipping'] = $this->lang->line('menu_shipping');
$this->load->view('templates/navigation', $data);
}
}
View :templates/navigation
<?php
print_r($shipping);
?>

How to create custom 404page

I want to create custom 404 page for my site.I mean when i type url as
http://example.com/anydummytext
need to redirect to custom 404page
How to create custom page for this
The simple way is create a controller you can name the error controller to any what you want.
Example
<?php
class Not_found extends CI_Controller {
public function index() {
// some content
$this->load->view('not_found');
}
}
Then on another controller you can redirect it
redirect('not_found');
Example Only
<?php
class Home extends CI_Controller {
public function index() {
$result = $this->some_model->get();
if ($result) {
// content
$this->load->view('home');
} else {
redirect('not_found');
}
}
}
The other option is in config/routes.php you can use codeigniter
$route['404_override'] = 'not_found'; // Note will not work in a subfolder
You can create a new controller or use existing controller to write down a function for loading the VIEW for 404.
class Nopage extends CI_Controller
{
/* Index function
*
* return void
*/
public function index()
{
$this->load->view('nopage_404');
}
}
}
Call the controller function in config->routes as below.
$route['404_override'] = 'nopage';

How to redirect from view to controller in codeigniter?

In my header view I wrote this code:
<?php
if($this->session->userdata('logged_in')) {
$query = $this->db->get_where('instructors', array('id' => $this->session->userdata('id')));
$insdatacheck = $query->row_array();
if($insdatacheck['name'] == '') {
redirect(base_url().'user/continueregistration');
} else { ?>
<script type="text/javascript">alert('test');</script>
<?php
}
}
?>
But it does not redirect to the following page. However, if I write this in the controller, it works properly. I wrote it in header view because I want to check it in every page where enters the user. How can I improve it and write in a proper way? Thanks in advance
I think instead of your header you should put your check inside your controller constructor.
class Test extends CI_Controller {
function __construct() {
parent::__construct();
// if not logged-in redirect to login page
if ($this->session->userdata('logged_in') == false) {
redirect('login'); // where you want to redirect
}
}
}
Another option is to create a base controller. Place the function in the base controller and then inherit from this.
To achieve this in CodeIgniter, create a file called MY_Controller.php in the libraries folder of your application.
class MY_Controller extends Controller
{
public function __construct()
{
parent::__construct();
}
public function is_logged_in()
{
$user = $this->session->userdata('user_data');
return isset($user);
}
}
Then make your controller inherit from this base controller.
class X extends MY_Controller
{
public function __construct()
{
parent::__construct();
}
public function do_something()
{
if ($this->is_logged_in())
{
// User is logged in. Do something.
}
}
}
First create session in the controller only,
Then we access session in any page,
$this->load->library('session');
$user=$this->session->userdata('logged_in');
if (!isset($user)) {
redirect(base_url().'user/continueregistration');
}
else {
<script type="text/javascript">alert('test');</script>
}

how to pass same fetched data on my everypage on codeigniter

Here is my controller code
public function index()
{
$this->load->model("mod_home");
$data['avoinics'] = $this->mod_home->getAvoinics();
$data['dir']="home";
$data['page']="index";
$this->load->view('main',$data);
}
for another page
public function about()
{
$this->load->model("mod_home");
$data['avoinics'] = $this->mod_home->getAvoinics();
$data['dir']="home";
$data['page']="about";
$this->load->view('main',$data);
}
But i don't want to send $data['avoinics'] again again. Is there any way to access a data from anypage.
How to use same data in a single view more than time.
foreach($avoinics as $avoinics):
$name=$avoinics->sc_name;
echo '<li>'.$name.'</li>';
endforeach;
if i use it again on same view page it's sowing error...
Yes, you can:
Create a global array
private $data = array();
In constructor
$this->load->model("mod_home");
$this->data['avoinics'] = $this->mod_home->getAvoinics();
Now your function will look like this
public function index() {
$this->data['dir']="home";
$this->data['page']="index";
$this->load->view('main',$this->data);
}
For second part, do not change the variable value
foreach($avoinics as $record){
echo '<li>'.$record['name'].'</li>';
}
$avoinics is intact now. You can use it again until you do not modify it.
A good example you might easily understand is when you need to call certain scripts or css files for a specific controller. You won't call it in every single page but yes in the constructor.
class yourController extends CI_Controller
{
private $data;
public function __construct()
{
$this->data['css'] = array('file1.css', 'file2.css');
$this->data['js'] = array('jquery.min.js', 'jquery-ui.min.js');
}
public function index()
{
$this->load->view('yourView', $this->data);
}
public function about()
{
$this->load->view('yourView', $this->data);
}
}
I recommend you to extend core ci_controller with my_controller and declare there your variable in constructor. Then in your new controllers extend your my_controller where you will have variable declaration.

Codeigniter Why I can't load view from MY_Controller

I want every controller to have a method _render_page, which loads the master template and passes the data object.
My home controller class looks like this:
class Home extends MY_Controller {
function __construct() {
parent::__construct();
}
public function index() {
$data['title'] = "Site title";
$data['the_view'] = 'welcome_message';
$this->_render_page($this->layout, $data);
//$this->load->view($this->layout, $data); //This works ok..
}
}
MY_controller class:
class MY_Controller extends CI_Controller {
public $layout;
public $viewdata;
public function __construct() {
parent::__construct();
$this->layout = 'layout/master_template';
$this->viewdata = null;
}
public function _render_page($view, $data=null, $render=false) {
$this->viewdata = $data;
$this->viewdata['the_view'] = $view;
if($this->ion_auth->logged_in()) {
$user_obj = $this->ion_auth->user()->row();
$usr_data['username'] = $user_obj->username;
$user_obj = null;
$this->viewdata['usr_data'] = $usr_data;
}
$this->load->view($this->layout, $this->viewdata); //The code crashes here
}
}
When I browse to home controller I get nothing, just white screen no errors...
Found a solution: I'm calling _render_page in a wrong way.
Instead of this:
$this->_render_page($this->layout, $data);
I should call like this:
$this->_render_page('welcome_message', $data);
Of course, that's what this function is about - to load a master page and pass the view name as member of $data, so the master page will know which view to load.
See, you need to understand the flow going,
when you call your class home , it extends MY_Controller, CI will look for MY_Controller, the constructor of your MY_controller gets executed after which CI starts executing the constructor of your home controller then your default method of home controller,
so in order to make it work you need to call _render_page()-
change your MY_Controller like -
class MY_Controller extends CI_Controller {
public $layout;
public $viewdata;
public function __construct() {
parent::__construct();
$this->layout = 'layout/master_template';
$this->viewdata = null;
$this->_render_page($this->layout, $data=null, $render=false); // call your method
}
public function _render_page($view, $data=null, $render=false) {
$this->viewdata = $data;
$this->viewdata['the_view'] = $view;
if($this->ion_auth->logged_in()) {
$user_obj = $this->ion_auth->user()->row();
$usr_data['username'] = $user_obj->username;
$user_obj = null;
$this->viewdata['usr_data'] = $usr_data;
}
$this->load->view($this->layout, $this->viewdata); //The code crashes here
}
}

Categories