codeigniter3 controller to controller functions - codeigniter

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.

Related

Laravel 4: Responding to AJAX requests from controller

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.

Get data generated on another controller

I have a simple logic problem. I'm starting on use CodeIgniter and I'm understand the Controller concept now. The view, for instance, is used only to generate content (not pre-proccess data), controller to get all infos need to view. Fine.
My problem is: I have a poll that is called as /poll/1 from an iframe, and I like to print it in other moment on another controller. This path is relatives to Poll::index(1) (logically talking) and I'm on Content::index().
I don't found explanation for cases like that on the CI UserGuide.
How I do?
Thanks.
Edit: I'll do an example code:
class Blog extends CI_Controller {
function index(){
// Do some prints
// Executes Poll::index(1), but store on some string
// Do some prints
}
}
class Poll extends CI_Controller {
function index($id){
// Do some prints
}
}
The idea is that: /poll/1 works and /blog too (but this second will print more content, with the poll).
hummm interesting i think using ob_start() might just work for you, if it was me i would rather use a ajax call to display poll data
here is the code.
class Blog extends CI_Controller {
function index(){
// Do some prints
// Executes Poll::index(1), but store on some string
ob_start();
Poll::index(1)
// You can now use this $output value to display or store in db or store in session,
// but remember CI session can only hold upto certain length as it uses cookie
$output = ob_get_contents();
ob_end_clean();
// Do some prints
}
}
class Poll extends CI_Controller {
function index($id){
// Do some prints
}
}
One way which is my favorite is use one as a super class so class Poll extends blog. This allows your poll to take advantage of your blog methods. Then you can use any parent methods and load the proper views in which ever class#method you want.

Codeigniter reusable sections

I have a table of data from a database that I want to display on various pages of my website. Ideally, i would like to just have an include or something that will go off and get the data, and return the html table. The html and data will be identical everytime I need to use this.
I wanted to know the best way of doing this
Thanks
EDIT
If this helps, something similar to a Django "inclusion" custom tag...for any django developers reading
you need to pass the variable $data to the view method.
This is your code:
function load_my_view(){
$this->load->model('my_table');
$data['my_results'] = $this->my_table->my_data();
$this->load->view('my_view');
}
Please change it to this in order to load the $data into the view:
function load_my_view(){
$this->load->model('my_table');
$data['my_results'] = $this->my_table->my_data();
$this->load->view('my_view',$data);
}
You should use a function in a model to fetch the data you need. Your controller calls the model function and sends the returned information to a view. You don't need to use traditional php includes with Codeigniter. I recommend a review of the user guide. It's very good and will tell you all the basic stuff you need to know to develop with CI. But to get you started, you watn to use Models, Views, and Controllers. Your url will tell CI what controller and function inside that controller to run. If your url is
http://www.example.com/my_controller/load_my_view
Then CI will do what is inside the load_my_view function in the my_controller controller. function load_my_view in turn instantiates a model "my_table" and runs a database query, returns information that the controller sends to the view. A basic example follows:
Your model
class my_table extends CI_Model{
function my_data(){
$this->db->select('column_1,column_2,column_3');
$this->db->from('my_table');
$query = $this->db->get();
if($query->num_rows()>0){
$result = $query->result();
}
else{
$result = false;
}
return $result;
}
}
Your controller
class my_controller extends CI_Controller{
function load_my_view(){
$this->load->model('my_table');
$data['my_results'] = $this->my_table->my_data();
$this->load->view('my_view');
}
}
Your View
<ul id = "my_db_results">
<?php foreach($my_results as $result):?>
<li><?php echo $result->column_1." : ".$result->column_2." ( ".$result->column_3." )";?></li>
<?php endforeach;?>
</ul>
It looks like a good oportunity to use cache: http://codeigniter.com/user_guide/libraries/caching.html
Ok, so here is one thing that worked for me, but its definitely not perfect.
I created a view in which made a call to the model getting the data then put the data into a table. This way, I only have to include this view to put the table anywhere.
I understand this completely ruins the point of having a MVC framework, but hopefully it demonstrates what I want to do...and it works

Need help figuring out how to write my zend view helper

I'm fairly new to Zend Framework and MVC in general so I'm looking for some advice. We have a base controller class in which we have some methods to obtain some user information, account configurations, etc.
So I'm using some of those methods to write out code in various controllers actions, but now I want to avoid duplicating this code and further more I would like to take this code outside of the controller and in a view helper as it is mainly to output some JavaScript. So the code in the controller would look like this:
$obj= new SomeModel ( $this->_getModelConfig () );
$states = $obj->fetchByUser ( $this->user->getId() );
//Fair amount of logic here using this result to prepare some javascript that should be sent to the view...
The $this->_getModelConfig and $this->user->getId() are things that I could do in the controller, now my question is what is the best way to pass that information to the view helper once i move this code out of the controller ?
Should I just call these methods in the controller and store the results into the view and have the helper pick it up from there ?
Another option I was thinking of was to add some parameters to the helper and if the parameters are passed then I store them in properties of the helper and return, and when called without passing the parameters it performs the work. So it would look like this:
From controller:
$this->view->myHelper($this->user->getId(), $this->_getModelConfig());
From view:
<?= $this->myHelper(); %>
Helper:
class Zend_View_Helper_MyHelper extends Zend_View_Helper_Abstract
{
public $userId = '';
public $config = null;
public function myHelper ($userId = null, $config = null)
{
if ($userId) {
$this->userId = $userId;
$this->config = $config;
} else {
//do the work
$obj = new SomeModel($this->config);
$states = $obj->fetchByUser($this->userId);
//do the work here
}
return $this;
}
}
Any advice is welcomed!
Firstly the ASP style ending tag here at "$this->myHelper(); %>" is bad practice, with that said it is more advisable to keep the logic in the model and the controller just being used to call the model, get the results and spit that to the view for viewing.
what I would do is, if i simply want to pass a bunch of values to the view, i stuff them in an associative array and send them over.
anyway you should not be doing your ...
"//Fair amount of logic here using this result to prepare some javascript that should be sent to the view..."
part in the controller, I would advice you to make a new model that does that logic stuff for you, and you just call your model in the controller pass it what ever arguments that are needed and then spit the result of that to the view.
The best way is to get the data from your model throught your controller, and then pass to the view. But if you really need a custom helper to echo the view parts, we only will know if you say exactly what you're trying to do.
If you already have this logic in a helper, try to just pass the parameters in your view myhelper($this->params); ?>
You may want take a look at this approach too:
// In your view to put javascript in the header
// You can loop trought your data and then use it to generate the javascript.
<?php $this->headScript()->captureStart(); ?>
$().ready(function(){
$('#slideshow').cycle({
fx: 'fade',
speed: 1000,
timeout: 6500,
pager: '#nav'
});
});
<?php $this->headScript()->captureEnd() ?>

Codeigniter common templates

Let's say that I have a website that has 100 different pages. Each page uses a common header and footer. Inside the header is some dynamic content that comes from a database.
I'd like to avoid having to have code in every single controller and action that passes this common code into the view.
function index()
{
// It sucks to have to include this on every controller action.
data['title'] = "This is the index page";
data['currentUserName'] = "John Smith";
$this->load->view("main_view", data);
}
function comments()
{
// It sucks to have to include this on every controller action.
data['title'] = "Comment list";
data['currentUserName'] = "John Smith";
$this->load->view("comment_view", data);
}
I realize that I could refactor the code so that the common parts are in a single function and the function is called by the action. Doing so would reduce SOME of the pain, but it still doesn't feel right since I'd still have to make a call to that function every time.
What's the correct way to handle this?
One way I have been doing this is to extend the default controller class. You can read up on extending classes with MY_Controller in the user guide. Inside this extended class you can include something that you ALWAYS want to do, like render the page header template before the main content, or authorise a users access etc.
class MY_Controller extends Controller {
function __construct()
{
parent::Controller();
//code to always do goes here
echo 'Always print this comment';
$this->load->view('partials/template_start');
}
}
Then you can have your normal controller class extend THIS class by using
class MyControllerNameHere extends MY_Controller {
function __construct()
{
//setup here
}
function index()
{
echo 'Only print this bit when this method is called';
$this->load->view('partials/MYPAGENAMEHERE');
}
}
There are other ways of doing this, I use a mixture of the above and William's Concepts Codeigniter Template library. Do a bit of searching - there are a few solutions for you.
I had a similar situation. I created an 'includes' folder, and in there put a file that had the repetitive code from my controllers. Then in the controllers just include('/path/to/includeFile.php');
Don't know if it's the "correct" way, but it works well for me.
I ran across this after a search of their site. http://codeigniter.com/wiki/Header_and_footer_and_menu_on_every_page/ I'll review this page and its links, then post my thoughts.

Resources