I am trying to make page info rendered from database.
I have database:
page | title | description
main | Welcome | This is the main page
Controller to get page data and render View
class Main extends CI_Controller {
function __construct()
{
parent::__construct();
$this->load->helper(array('url', 'html', 'assets'));
$this->load->model('pages_model');
}
public function index() {
// This is a page variable
// in this case it will be "main"
$page = strtolower(basename(__FILE__, '.php'));
// Page data
$data['pg'] = $this->pages_model->page();
// Render
$this->load->view('templates/header', $data);
$this->load->view('pages/main', $data);
$this->load->view('templates/footer', $data);
}
}
Then Model where i try to fetch data for specific page
Class Pages_model extends CI_Model {
function page()
{
$query = $this->db->select('*')->where('page', $page)->get('pages');
return $query->result();
}
}
But i get error "undefined variable $page in model". How can i fix it?
You missed to pass "$page" in model. update your code as below:
In controller:
// Page data
$data['pg'] = $this->pages_model->page($page);
And in model
function page($page)
Related
I have some problem with CodeIgniter 3.
When I try to access URL with the parameter like these http://localhost/crm/Customer/update/3
The result is infinite loop page refresh.
This does not happen if I access other view or URL.
For example : http://localhost/crm/Customer/list
Below is my controller file :
class Customer extends CI_Controller {
function __construct() {
parent::__construct();
$this->load->helper(array('form', 'url', 'customer'));
$this->load->database();
$this->load->library('session');
$this->load->model(array('Auth', 'Model_customer'));
$this->_init();
}
function _init() {
$this->output->set_template('index');
// $this->load->section('sidebar','template/sidebar');
}
public function index(){
...
$this->load->view('customer/index');
}
function update($id) {
// TEST
$data['id'] = $id;
$this->load->view('customer/update2', $data);
}
}
Any help will be valuable. Thanks
I'm with a doubt at this post:
http://www.ahowto.net/php/easily-integrateload-phpexcel-into-codeigniter-framework/
I've done up to libraries part (Excel.php).
But in the tutorial, where it starts Example Usage, where exactly I need to put all that code? In a new controller? Here in my project I tried to create a new Controller called Report. In report I've this code:
public function readReport() {
$this->load->library('excel');
$this->excel=PHPExcel_IOFactory::load(APPPATH."/third_party/teste.xlsx");
$this->excel->setActiveSheetIndex(0);
//get some value from a cell
$number_value= $this->excel->getActiveSheet()->getCell('C1')->getValue();
$data['header'] = $number_value;
$this->load->view('pages/home', $data);
}
But I have also a Pages controller to control the pages of Views, and when I try to output something of PHP Excel is not possible. In my Pages.php I've wrote: $data['header'] = $number_value; and in view . But the variable "number_value" is not in Pages.php because it's only at Report.php. How can I do to output the excel data at my home.php (view) correctly?
Here is my pages.php controller
class Pages extends CI_Controller {
public function view ($page = 'home') {
if (!file_exists(APPPATH.'views/pages/'.$page.'.php')) {
show_404();
}
$data['title'] = str_replace("_", " ", $page);
$data['header'] = $number_value;
$this->load->helper('url');
$this->load->view('templates/header', $data);
$this->load->view('pages/'.$page, $data);
$this->load->view('templates/footer', $data);
}
}
I'm not very familiar with PHPExcel but here are some thoughts.
First, to use a library in a Controller it must be loaded in that controller. You cannot access one controller from another. You could duplicate the code from Report in Pages but that seems a waste. You need reuseable code.
One "reuseable" approach is to create a model that uses the excel library. This will make it easy to reuse PHPExcel code just by loading the model in any controller.
A model version including a readReport() function might look like this.
class excel_model extends CI_Model
{
protected $excel;
function __construct()
{
parent::__construct();
$this->load->library('excel');
}
function readReport()
{
$this->excel = PHPExcel_IOFactory::load(APPPATH."/third_party/teste.xlsx");
$this->excel->setActiveSheetIndex(0);
//get some value from a cell
return $this->excel->getActiveSheet()->getCell('C1')->getValue();
}
}
Pages controller should be modified as follows.
class Pages extends CI_Controller
{
public function view($page = 'home')
{
//The following check isn't needed, codeigniter will do this automatically
//if (!file_exists(APPPATH.'views/pages/'.$page.'.php')) {
//show_404();
//}
$this->load->model('excel_model');
$this->load->helper('url');
$data['title'] = str_replace("_", " ", $page);
$data['header'] = $this->excel_model->readReport();
$this->load->view('templates/header', $data);
//You don't have to keep sending $data to the views because
//any variables loaded by the first call to load->view()
//will be visible the all other views loaded in this function.
$this->load->view('pages/'.$page);
$this->load->view('templates/footer');
}
}
I have a Controller called Stats which is responsible to get some stats and show them in my application.
Stats.php:
<?php
class Stats Extends CI_Controller{
public function index()
{
$this->load->model('Stats_model');
$return['users'] = $this->Stats_model->get_users();
$return['photos'] = $this->Stats_model->get_photos();
$return['members'] = $this->Stats_model->get_members();
$this->load->view('stats',$return);
}
}
In my application i have 3 total views with their controllers. Home,About,Contact - Home_controller, About_controller, Contact_controller.
In start of any of these 3 views i have a section which i want to place the the stats. So the stats will be visible in any page of my application.
How can i load a view (stats) to take data from a controller (Stats) without calling it? When the home view called then the Home controller called , NO the stats.
I don't want to call a separate stats page. I want the stats to be visible in top of any page in my app. How can i achieve that in CI?
Thanks
You can customize CI_Controller by adding MY_Controller in directory ./application/core/ and move the codes in Stats controller into it's constructor
like:
<?php
class MY_Controller Extends CI_Controller
{
protected $_stat_view;
public function __construct()
{
$this->load->model('Stats_model');
$return['users'] = $this->Stats_model->get_users();
$return['photos'] = $this->Stats_model->get_photos();
$return['members'] = $this->Stats_model->get_members();
//specify true to view's third parameter will make it return
//view content instead of render and display it on browser
$this->_stat_view = $this->load->view('stats',$return, true);
}
}
And then your Home,About,Contact controller need extends this new MY_Controller
<?php
class Home_Controller extends MY_Controller
{
public function __construct()
{
parent::__construct();
}
public function index()
{
$data[stats_section] = $this->_stat_view;
//In home view just echo $stat_section
$this->load->view('home', $data);
}
}
FYI you can modify prefix MY_ in ./application/config/config.php, set what prefix name you like to config item $config['subclass_prefix'].
Suppose i have a controller called home like this
class Home extends CI_Controller{
public function __construct()
{
parent::__construct();
//load the settings model
$this->load->Model('settings_model');
//get the all settings and store it into a variable
$siteSettings = $this->settings_model->SiteSettings();
//how to pass the data to view
$data['site'] = $siteSettings;
}
public function index()
{
//some code and pass the value to view
$data["some_item"] = "some value";
//Load the view
$this->load->view("home",$data);
}
public function SomeMethod1()
{
//some code and pass the value to view
$data["some_item"] = "some value";
//Load the view
$this->load->view("home",$data);
}
public function SomeMethod2()
{
//some code and pass the value to view
$data["some_item"] = "some value";
//Load the view
$this->load->view("home",$data);
}
}
But my problem is i want to pass $siteSettings to my each method. I don't want to fetch the data every time from settings_model for my different method of home controller. I just want to get the data from database on __construct() and pass the value to each method when i call the different method.
How can i achieve this? Should I use a public variable and store the fetched data to this variable and call the variable from different method?
Set that in session. and can access all over the project.
public function __construct()
{
parent::__construct();
$this->session->unset_userdata('site'); # unset on each and every time
$this->load->Model('settings_model');
$siteSettings = $this->settings_model->SiteSettings();
$this->session->set_userdata('site', $siteSettings); # Set after end of __construct
}
Or do like this
public function __construct()
{
parent::__construct();
$this->load->Model('settings_model');
$this->data['site'] = $this->settings_model->SiteSettings();
}
In function
$this->load->view("name",$this->data);
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