Before I added form helper I get all result and without error. But, when I call form helper I just get blank page without error.
Controller Script:
class Reza extends CI_Controller
{
function __construct()
{
parent::__construct();
$this->load->library(array("rez_lib"));
}
function index(){
$this->rez_lib->display("home");
}
}
library Script:
class Rez_lib
{
protected $_ci;
function __construct(){
$this->_ci =& get_instance();
}
function display($temp, $data=null){
$data['header'] = $this->_ci->load->view("construct/header",$data,true);
$data['sidebar'] = $this->_ci->load- >view("construct/sidebar",$data,true);
$data['content'] = $this->_ci->load->view("page/".$temp,$data,true);
$this->_ci->load->view("construct/all",$data,true);
}
}
First off the blank screen is because you do not have debugging enabled.
Go to index.php and set the 'ENVIRONMENT' constant to 'development' when developing.
Secondly it seems you have several typos in your library class.
In your constructor you have an extra space between & and get_instance(): $this->_ci =& get_instance();
In your class body you also have an extra space between load- and ->view (when loading your sidebar) $data['sidebar'] = $this->_ci->load- >view("construct/sidebar",$data,true);
Finally you are returning the view as data, since the third parameter is set to true. See:
There is a third optional parameter lets you change the behavior of the method so that it returns data as a string rather than sending it to your browser. This can be useful if you want to process the data in some way. If you set the parameter to TRUE (boolean) it will return data. The default behavior is false, which sends it to your browser. http://www.codeigniter.com/user_guide/general/views.html
Related
Okay, so i have pages controller and user_authenticator controller.
pages controller is like a terminal to my views whilst the user_authenticator controller does the functions that relates to users like registration/logging in.
Whenever i'm done with a function in user_authenticator say for example logging in, how do i load the views via pages controller?
Login->user_auth(controller)->acc_model(model)->user_auth(controller)->view.
to
Login->user_auth->acc_model->pages(controller)->view.
It would be a boon for me if you guys can tell me if what i'm doing is impractical and a better way to do things. Or maybe i should just stick to loading views on the controller i used previously.
EDIT: so i may have forgotten the purpose of my pages controller but i remembered due to a moment of clarity from my foggy and tired mind.
I made a pages controller solely to load views, i guess in a sense, pages won't be loading ALL view but atleast most of the views, for example, if i had links in my views to other views, i would link them via the pages.
For specific functions that need specific controllers i guess i can let them handle loading some views.
Then again, if someone could tell me what i'm doing is a waste of time and should just delete pages controller please tell me so, i'd like to know why.
also if you have any suggestions for further uses of my pages controller thatd be great!
Also regarding session. I have a base controller.
<?php
class MY_Controller extends CI_Controller {
public function __construct()
{
parent::__construct();
}
public function is_logged_in($data){
$session = $this->session->userdata();
if($session['isloggedin']['username'] == ''){
return isset($session);
}else{
return FALSE;}
}
}
?>
How do i make it so that it automatically runs and checks for every controller i load if there are any session set?
Do i have to put it into a constructor? or do i have to call the base controller method from all controllers?
Here is the best solution for you.
You can use Hooks
Step1:
application/config/config.php
$config['enable_hooks'] = TRUE;//enable hook
Step2:
application/config/hooks.php
$is_logged_in= array();
$is_logged_in['class'] = '';
$is_logged_in['function'] = 'is_logged_in';//which function will be executed
$is_logged_in['filename'] = 'is_logged_in.php';//hook file name
$is_logged_in['filepath'] = 'hooks';//path.. default
$is_logged_in['params'] = array();
$hook['post_controller_constructor'][] = $is_logged_in;//here we decare a hook .
//the hook will be executed after CI_Controller construct.
//(also u can execute it at other time , see the CI document)
Step3:
application/hooks/is_logged_in.php //what u decared
<?php
//this function will be called after CI controller construct!
function is_logged_in(){
$ci =& get_instance();//here we get the CI super object
$session = $ci->session->userdata();//get session
if($session['isloggedin']){ //if is logged in = true
$ci->username = 'mike';//do what you want just like in controller.
//but use $ci instead of $this**
}else{
//if not loggedin .do anything you want
redirect('login');//go to login page.
}
}
Step4:application/controller/pages.php
<?php
class pages extends CI_Controller{
function construct ........
function index(){
echo $this->username;//it will output 'Mike', what u declared in hook
}
}
Hope it will help u.
I'm using CodeIgniter to build a multilanguage web application. I have English and other languages under /system/languages/ folder and I've created a model responsible for changing the working language at run-time.
By default CodeIgniter is working in French as defined in /application/config/config.php
$config['language'] = 'french';
Later, according to a URI segment the model changes the language accordingly, simplified example bellow:
class multilang extends CI_Model {
public function __construct() {
parent::__construct();
if ($this->uri->segment(1) == 'en') {
$this->config->set_item('language', 'english');
}
}
}
This model is the first model listed under the auto load settings in /application/config/autoload.php and I can confirm that the language is indeed changed dynamically by calling:
echo $this->config->item('language');
However the built in form validation library does not take into account the changed language, instead only shows error messages from the language hard coded in the settings file /application/config/config.php in this case French.
At first I assumed this was because the form validation was loaded before the multilang model. To make sure the model was loaded first, I modified the form validation constructor to load the model before anything else like this:
public function __construct($rules = array())
{
$this->CI =& get_instance();
$this->CI->load->model('multilang');
// normal code after....
}
This made sure the model loaded before the form validation. Unfortunately this wasn't enough and the form validation still ignores the language when changed during run-time. Anyone knows why this happens?
Thank you.
The problem was that I was doing AJAX requests that didn't took into account the URI segment that contained the language abbreviation, because the URI for AJAX requests didn't needed the language segment in the first place, so I totally forgot about it.
Therefore I used the session cookie to store the language. Changing the multilang constructor to:
class multilang extends CI_Model {
public function __construct() {
parent::__construct();
# store lang between session
$data = $this->session->all_userdata();
if (isset($data['language'])) {
$lang = $data['language'];
# if lang was changed between sessions
if ($this->uri->segment(1) == 'fr'){
$lang = 'french';
} else if ($this->uri->segment(1) == 'en'){
$lang = 'english';
}
# if lang was changed using one of the lang abbreviations
# overule session setting
if ($this->uri->segment(1) == 'en') {
$lang = 'english';
} else if ($this->uri->segment(1) == 'fr') {
$lang = 'french';
}
$this->config->set_item('language', $lang);
$this->session->set_userdata('language', $lang);
} else {
if ($this->uri->segment(1) == 'en') {
$this->config->set_item('language', 'english');
$this->session->set_userdata('language', 'english');
} else if ($this->uri->segment(1) == 'fr') {
$this->config->set_item('language', 'french');
$this->session->set_userdata('language', 'french');
}
}
}
}
Note: The change to the form_validation constructor wasn't required.
Answer provided for future reference, and to remind people of little things we miss. It was so obvious right! Well this might help the next one who forgets.
Closing question.
I'm trying to generate ajax specific responses from my controllers by using the Request::ajax() method, which is working just fine. The only problem is that the way I have it set up right now isn't really a nice looking solution.
My controller:
class HomeController extends BaseController {
protected $layout = 'layouts/main';
public function __construct()
{
$this->beforeFilter('auth');
}
public function getIndex()
{
$view = View::make('content.home.index');
if(Request::ajax()) return $view; //For ajax calls we only want to return the content to be placed inside our container, without the layout
$this->layout->menu = 'content.menu';
$this->layout->content = $view;
}
}
So right now, for every method I define within my controllers I need to add the code snippet that checks for an AJAX request and returns a single view if the statement returns true.
This leads to my question that is probably more PHP related than it is to the framework;
Is there a way of executing my AJAX check on every method call, without actually placing it inside the method? Or is there some other solution to keep my code DRY?
Thanks in advance!
PS: This is my first post on stackoverflow, so feel free to correct me if I made any mistakes
Create a new barebone layout named 'layouts/ajax' (or any name you like).
<?php echo $content ?>
In your Base controller, override this setupLayout() function.
protected function setupLayout()
{
if ( ! is_null($this->layout))
{
$layout = Request::ajax() ? 'layouts/ajax' : $this->layout;
$this->layout = View::make($layout);
}
}
Change your getIndex() function to this.
public function getIndex()
{
$view = View::make('content.home.index');
$this->layout->menu = 'content.menu';
$this->layout->content = $view;
}
Now non-ajax requests will be rendered using layout set in the controller, where as ajax requests will receive whatever set to $this->layout->content.
Note : Controller will neglect the layout setup in setupLayout(), if the called method returns truthy value. So this method will not work for functions like below.
public function getIndex()
{
return View::make('content.home.index');
}
You could just change the layout property, in the constructor, if it's an ajax request:
public function __construct()
{
$this->beforeFilter('auth');
if(Request::ajax()) {
$this->layout = '';
}
}
If it doesn't work try setting it to NULL instead.
Why would you return a VIEW via ajax? Are you using it to create a SPA? If so there are better ways. I'm generally against returning HTML via AJAX.
The route I'd go in your position is probably opposite of how you're doing it. Render the view no matter what, if the request is ajax, pass the extra data back and have JS render the data on the page. That's essentially how most Javascript MVC frameworks function.
Sorry if I am totally missing the point here, just going on an assumption of your end goal with the info you provided.
I put the following code in every controller under public function index(). As of now I have 3 controllers and it will increase until my website is finish. I need the code below in all pages (i.e. views).
$type = $this->input->post('type');
$checkin = $this->input->post('sd');
$checkout = $this->input->post('ed');
My question is where can I put the code above in just one location so it will be available on all pages (i.e. views) and avoid putting it in every controller.
If you have for example a main view file, and you need that code on every page, then I suggest you put in the main view file (view/index.php)
I think, with #KadekM answer, you should call a function every time in every controller, because you sad, you want this code in every controllers every function.
You can create your own controller (for example MY_cotroller) extending CI_controller, put shared code there, and then your three controllers should extend MY_controller.
You can then call it wherever you need it (or even put it to constructor if you need it everywhere).
Here's the sample I promised (assuming you have default codeigniter settings)
in core folder create file named MY_Controller.php
class MY_Controller extends CI_Controller{
protected $type;
protected $checkin;
protected $checkout;
protected $bar;
public function __construct()
{
parent::__construct();
$this->i_am_called_all_the_time();
}
private function i_am_called_all_the_time() {
$this->type = $this->input->post('type');
$this->checkin = $this->input->post('sd');
$this->checkout = $this->input->post('ed');
}
protected function only_for_some_controllers() {
$this->bar = $this->input->post('bar');
}
protected function i_am_shared_function_between_controllers() {
echo "Dont worry, be happy!";
}
}
then create your controller in controllers folder
class HelloWorld extends MY_Controller {
public function __construct() {
parent::__construct();
}
public function testMyStuff() {
// you can access parent's stuff (but only the one that was set), for example:
echo $this->type;
//echo $this->bar; // this will be empty, because we didn't set $this->bar
}
public function testSharedFunction() {
echo "some complex stuff";
$this->i_am_shared_function_between_controllers();
echo "some complex stuff";
}
}
then for example, another controller:
class HappyGuy extends MY_Controller {
public function __construct() {
parent::__construct();
$this->only_for_some_controllers(); // reads bar for every action
}
public function testMyStuff() {
// you can access parent's stuff here, for example:
echo $this->checkin;
echo $this->checkout;
echo $this->bar; // bar is also available here
}
public function anotherComplexFunction() {
echo "what is bar ?".$this->bar; // and here
echo "also shared stuff works here";
$this->i_am_shared_function_between_controllers();
}
}
Those are just examples, of course you won't echo stuff like this, but pass it to view etc., but I hope it's enough for illustration. Maybe someone comes with better design, but this is what I've used a few times.
id suggest , adding it to a library and then auto load the library so that each and every page on your website can access the same.
for autoloading reffer : autoload in codeigniter
hi i am using codeigniter , in my controller constructor sometimes i use $this sometimes $this->ci
in two constructors i have use like this
public function __construct()
{
$this->ci =& get_instance();
$this->ci->load->library('form_validation');
$this->ci->load->library('catalog/CatalogManager');
}
function __construct()
{
parent::__construct ();
$this->ci = & get_instance ();
$this->load->library ( 'auth_lib' );
$this->load->library ( 'session' );
}
when passing data to view i use
$this->ci->data and $this->data in above two cases .
neither gives errors , but i am confused , what is the correct use.
please help...........
All controllers extend the main CI_Controller, so calling something like $this->load means accessing the parent method load() inside the parent class CI_Controller.
$this->ci works because with $this->ci = &get_instance() you're calling a reference to the main controller class...again. If you look in the bootstrap file (IIRC. Or the codeigniter.php file) there's the function get_instance(), which does nothing but return (by reference) the instance of the CI_Controller class.
So, basically, calling $this->ci->load and $this->load are the same exact thing, only that the first is unnecessary within a Controller/Model/View because the system is already doing that in the parent class (through the method load).
If you have a look at libraries, for ex., you'll see instead that using $this->ci->method() is necessary, because you need to have available all the methods of the CI_Controller, which is a kind of "super class" that drives the whole framework.
Have a look at the loader class and the CodeIgniter class to grasp how CI internally works.
Agree with the answer above, but actually, load is a variable, not a function. it is a object of the class CI_Loader, when you call $this->load->libray(), in fact it calls the library() function in CI_Loader.
$this is nothing. It just use to store the value. It just like a variable.