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');
}
}
Related
I'm using CodeIgniter to access a variety of form types
I have a directory such as this:
-views
--resources
---app1
----form.php
---app2
----form.php
---app3
----form.php
---app4
----form.php
My class is currently very basic, but this
class Resources extends CI_Controller {
public function app1($page = '')
{
$data['title'] = ucfirst($folder); // Capitalize the first letter
$this->load->view('templates/header', $data);
$this->load->view('resources/app1/form.php', $data);
$this->load->view('templates/footer', $data);
}
public function app2($page = '')
{
$data['title'] = ucfirst($folder); // Capitalize the first letter
$this->load->view('templates/header', $data);
$this->load->view('resources/app2/form.php', $data);
$this->load->view('templates/footer', $data);
}
}
This seems very verbose and unnecessary to have a method for every form. However I can't find how I can change the directory without creating a new method. I would ideally like a method where I can pass in a new directory as an arg like $page can be. Eg:
class Resources extends CI_Controller {
public function view($page = '')
{
$data['title'] = ucfirst($folder); // Capitalize the first letter
$this->load->view('templates/header', $data);
$this->load->view('resources/'. $folder. '/form.php', $data);
$this->load->view('templates/footer', $data);
}
}
However, it seems CodeIgniter doesn't allow this. Can anyone suggest a way in which this can work?
Actually you can.
Create a base_controller inside your core folder and call it MY_Controller.php and make it extends CI_Controller and create a method inside MY_Controller and name it render, render_view, view whatever you want and inside that function load you layout partials and template and just pass the view to it: application/core/MY_Controller.php
class MY_Controller extends CI_Controller {
protected $data = array();
public function render_view($view = '')
{
$this->load->view('templates/header', $this->data);
$this->load->view('view_path/'. $view, $this->data);
$this->load->view('templates/footer', $this->data);
}
}
and for every controller in your application make it extend MY_Controller and whenever you wanna render a view use render_view($view) and you got you header and footer preloaded, and that's the simplest way of making it DRY.
Finally in your controller it should be like this:
class Resources extends CI_Controller {
public function app1($page = '')
{
// $data array in my_controller, it will automatically be passed inside render_view
$this->data['title'] = ucfirst($folder); // Capitalize the first letter
$this->render_view('app1/form');
}
public function app2($page = '')
{
$this->data['title'] = ucfirst($folder); // Capitalize the first letter
$this->render_view('app2/form');
}
}
Calling your function "view" is almost certainly a bad idea... it's used by CI for the $this->load->view() for starters.
public function app_form($page = '')
{
$data['title'] = ucfirst($folder); // Capitalize the first letter
$this->load->view('templates/header', $data);
$this->load->view('resources/'. $page. '/form.php', $data);
$this->load->view('templates/footer', $data);
}
That should work but how are you going to call the functions? Via the routes.php file?
My template parser looks like this (p/s the .'/'. is for readability):
$this->parser->parse($this->settings['theme'].'/'.'header', $data);
$this->parser->parse($this->settings['theme'].'/'.'register', $data);
$this->parser->parse($this->settings['theme'].'/'.'footer', $data);
I don't want to declare $this->parser->parse($this->settings['theme'].'/'.'header', $data); and $this->parser->parse($this->settings['theme'].'/'.'footer', $data); every time in my controller's functions.
How can I extend the MY_Parser.php so that I could use it like this instead:
$this->parser->parse($this->settings['theme'].'/'.'register', $data); will include the register.php between my header.php and footer.php automatically.
The benefit of doing this is to save 2 lines and if I have 20 functions, I can save 40 lines.
Just create a function (can be a helper, library extension or model):
function tpl($view, $data) {
$this->parser->parse($this->settings['theme'].'/'.'header', $data);
$this->parser->parse($this->settings['theme'].'/'.$view, $data);
$this->parser->parse($this->settings['theme'].'/'.'footer', $data);
}
If you want you can extend Parser and make a MY_Parser in the libraries folder and do:
class MY_Parser extends CI_Parser {
function tpl($view, $data) {
$this->parse($this->settings['theme'].'/'.'header', $data);
$this->parse($this->settings['theme'].'/'.$view, $data);
$this->parse($this->settings['theme'].'/'.'footer', $data);
}
}
Usage:
$this->parser->tpl($view, $data);
You could do this using $this->parser->parse() but that would require more code as you overwriting the default method and it's just as easy to introduce a new method.
UPDATE:
Using the MY_Parser method you might have to access $this->settings via $this->CI->settings thereby referencing the CI instance in CI_Parser depending on where this variable is coming from.
Create class with the name of your prefix class name in application/core folder and follow below code. $this->input->is_ajax_request() will only load view other then header and footer if request is from ajax. and in each controller you need to extend YOUR-PREFIX_Controller instead of CI_Controller
<?php
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class YOUR-PREFIX_Controller extends CI_Controller {
protected $header_data;
protected $footer_data;
protected $header_view;
protected $footer_view;
public function __construct() {
parent::__construct();
$this->header_view = 'path-to-header';
$this->footer_view = 'path-to-footer';
}
public function _output($output) {
if ($this->input->is_ajax_request()) {
echo ($output);
} else {
echo $this->load->view($this->header_view, $this->header_data, true);
echo ($output);
echo $this->load->view($this->footer_view, $this->footer_data, true);
}
}
}
?>
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)
I have anchor in header.php as below:
Backend
Also have the controller named backend.php in Controllers folder.
I also routed this code in routes.php file like
$route('default_controller')='frontend';
$route('backend')='backend';
Backend controller page is:
<?php
class Backend extends CI_Controller {
public function __construct(){
parent::__construct();
}
public function index(){
$data['title'] = 'Backend Page';
$this->load->view('templates/header', $data);
$this->load->view('backend/reg', $data);
$this->load->view('templates/footer');
}
}
Although getting error 404 Page not found.
Make sure all controller and models etc Ucfirst example Frontend.php instead of frontend.php
Codeigniter Docs http://www.codeigniter.com/docs
Auto load url helper in application.config/autoload.php
Change route from
$route('default_controller') ='frontend';
to
$route['default_controller'] = "frontend";
$route['backend'] = "backend";
I you have not set up you config to remove index.php with htaccess then use index.php in link.
Backend
Example controllers/Backend.php
<?php
class Backend extends CI_Controller {
public function __construct(){
parent::__construct();
}
public function index(){
$data['title'] = 'Backend Page';
$this->load->view('templates/header', $data);
$this->load->view('backend/reg', $data);
$this->load->view('templates/footer');
}
}
Example controllers/Frontend.php
<?php
class Frontend extends CI_Controller {
public function __construct(){
parent::__construct();
}
public function index(){
$data['title'] = 'Frontend Page';
$this->load->view('templates/header', $data);
$this->load->view('frontend/reg', $data);
$this->load->view('templates/footer');
}
}
Link here for htaccess examples for removing index.php on windows os https://github.com/riwakawebsitedesigns/htaccess_for_codeigniter
Try this one :
Backend // include also the folder where your backend file is stored
I hope this helps.
Consider my code:
<?php
class MY_Controller extends Controller {
public function __construct()
{
parent::Controller();
}
function _displayPage($page, $data = array()) {
$this->load->view('structure/header', $data);
$this->load->view($page, $data);
$this->load->view('structure/footer', $data);
}
}
?>
page.php
<?php
class Page extends MY_Controller {
function __construct() {
parent::__construct();
}
function index() {
$data['content'] = array('title'=>'hello world');
$this->_displayPage('home', $data);
}
}
?>
Upon loading my page on my browser, I get this error:
A PHP Error was encountered
Severity: Notice
Message: Undefined property: Page::$view
Filename: libraries/MY_Controller.php
Line Number: 11
Does anyone know what I'm doing wrong?
Thanks
In your library My_Controller you should be using the parent keyword instead of $this.
your code should look like so:
class MY_Controller extends Controller
{
public function __construct()
{
parent::Controller();
}
function _displayPage($page, $data = array())
{
parent::load->view('structure/header', $data);
parent::load->view($page, $data);
parent::load->view('structure/footer', $data);
}
}
If I understand what you're trying to accomplish correctly, you're wanting to setup a template that includes your header view and footer view, but without calling header and footer views for each controller you use throughout your application. Here's what I've done to accomplish this.
First, create a new folder under your views, for this example we'll call it 'includes'. Inside the newly created includes folder, create three files, header.php, footer.php and template.php. Setup your header and footer appropriately and then edit your template.php to look as follows:
<?php echo $this->load->view('includes/univ_header'); ?>
<?php echo $this->load->view($main_content); ?>
<?php echo $this->load->view('includes/univ_footer'); ?>
Now, from your controller you can define what view you would like to set as your 'main_content'. For example, if you have home.php in your views folder and you want to wrap it with your header and footer you would do so in your controller as follows:
function index() {
$data['content'] = array('title'=>'hello world');
$data['main_content'] = 'home';
$this->load->view('includes/template', $data);
}
Hope this helps!