Automatically call a function when inside a certain module/controller - laravel-4

Is it possible to call a function in a certain module every request?
Let say I have module name called 'configuration', on this module, I have a list of controllers and list of functions/methods. What I want is to automatically pass my "Menu" to the View without manually passing it on each methods and controllers.
This menu is only available when inside the 'configuration module.
// I have extended the base controller to create common functions
ConfigureController extends \BaseController
{
protected function processMenu() {
}
}
// One of my controller that needs to render processMenu()
SetupController extends ConfigureController
{
public index()
{
// I want to optimize this portion so that I do not have to call it evertime
$pass_to_view = $this->processMenu();
// I need to pass it again and again
return View::make('setup')->with('data', $pass_to_view );
}
}
PS. sample code only
Thank you in advance!

Use the BaseController constructor method __construct() and within the SetupController's constructor call parent::__construct();

This is where the view composers come handy.
Put your menu in a partial, include it in you layout, then register a view composer (doc here: http://laravel.com/docs/4.2/responses#view-composers).
You can put your register code anywhere, for instance you could create a file composers.php in app and include it in your app/start/global.php.

Related

How to make main menu public in all controllers

i have this code in controller
$Headercategory=Categories::where('status','1')->orderby('order')->get();
return view('front.home',['Headercategory'=>$Headercategory]
all my controlles will include "Headercategory" that mean i have to do same code with all controllers i have.
is there any way to make this code public in all project? without no need to add it in all controllers
As I understand, you want to pass categories variable in your all blade file. You can do that easily from /app/Providers/AppServiceProvider.php on boot method :
use View;
public function boot()
{
$Headercategory = Categories::where('status','1')->orderby('order')->get();
View::share(['Headercategory' => $Headercategory);
}
Now you can access $Headercategory anywhere from your blade

How to Call a controller function in another Controller in Laravel 5

im using laravel 5.
I need to call a controller function but this should be done in another controller.
I dont know how to do this
public function examplefunction(){
//stuff
}
And i have a Route for this function, so at
public function otherfunctioninothercontroller(){
// I need examplefunction here
}
how Can i do this?
1) First way
use App\Http\Controllers\OtherController;
class TestController extends Controller
{
public function index()
{
//Calling a method that is from the OtherController
$result = (new OtherController)->method();
}
}
2) Second way
app('App\Http\Controllers\OtherController')->method();
Both way you can get another controller function.
If they are not in the same folder, place use namespace\to\ExampleClass; on top of your file, then you are able to instantiate your controller.
You can simply instantiate the controller and call the desired method as follows
FirstController.php:
namespace App\Http\Controllers;
class FirstController extends Controller {
public function examplefunction() {
// TODO: implement functionality
}
}
SecondController.php:
namespace App\Http\Controllers;
class SecondController extends Controller {
public function test() {
$object = new FirstController();
$object->examplefunction();
}
}
Now, after i've answered the question, i would like to add the following comment:
Controllers are classes, all rules that applies to normal classes can be applied to them
However, instantiating a controller directly inside another controller to call a desired method signifies a problem in your design for the following 2 reasons:
A controller cannot obtain an instance of another controller directly
Controller should contain as little business logic as possible, and if possible none
The closest possible solution to what you want (WITHOUT BREAKING MVC) is to make an HTTP request to the route that points to the desired method (using cURL, for example) and read the response as the returned data
But this still doesn't make much sense in this scenario because after all you're making an HTTP request from a method in a controller in your project on your server to a method in a controller in your project on your server, seems like unnecessary overhead, right ?
As i said earlier, a controller should contain as little business logic as possible because the logic should stay inside specialized classes (commonly known as Service Classes), and when a processing is requested the controller simply delegates the job of processing to the appropriate service class which does the processing and returns the results to the controller which in turn sends it back as a response
Now imagine if you've the following scenario:
We've got an application that consists of 3 functionalities:
A user can register an account from web application
There's a mobile application that talks to an API to register a user
There's an admin panel, which he can use to add new user
Obviously you need to create 3 controllers, but those controllers contains repeated logic, would you copy/paste the code everywhere ?
Why not encapsulate this logic inside a service class and call it from the controller when needed ?
Let's say I have Controller1 and Controller2. I want to call a function of Controller1 from inside a function placed in Controller2.
// Controller1.php
class Controller1 {
public static function f1()
{
}
}
And on the other controller:
// Controller2.php
use App\Http\Controllers\Controller1;
class Controller2 {
public function f2()
{
return Controller1::f1();
}
}
Points to be noted:
f1() is declared static
A call to a controller from inside another controller is a bad idea. There is no sense of meaning of controllers then. You should just redirect to web.php to save safe whole architecture like this:
class MyController {
public function aSwitchCaseFunction(Request $requestPrm){
...
//getting path string from request here
...
switch($myCase){
case CASE_1:
return redirect()->route('/a/route/path');
....
}
}
}

Access an object of one class in other codeigniter

I have two controller classes in my codeigniter application, say class A and B.I just want to create an object of class A and access the functions declared in class A from class B.Something like:-
class A extends someclass
{
public function function1(){
$this->load->view('welcome_message');
}
}
}
class B extends someclass2
{
protected $object;
public function __construct()
{
parent::__construct();
$this->objectA = new A();
}
}
}
I want to access the function function1 from class B using the object objectA. How can i do this?
Please help.
Thanks
well actually this is not the proper way in codeigniter. Actually when you have common functions in and you want to use them in 2 or more controllers. The best way is to create base controller in core folder with name of MY_Contoller and extend it from CI_Contoller. Write your common function in MY_Contoller. Now you have to extend all your controllers from MY_Contoller instead of CI_Contoller. You can do the same with Model.
Cross-controller access goes against CI best practice.
Either inherit both controllers from a controller that holds this common functionality (don't forget to prefix the function with '_' so it's inaccessible via url routing) or create a library that contains your re-usable functionality. A helper can also work.

default language codeigniter

i want to run this code at the first of all my webpages,
I'm using codeigniter
the code is:
if(!$this->session->userdata('lang')):
$this->session->set_userdata('lang','ar');
endif;
how to do that?
If you haven't already, it may be worth looking at CodeIgniter's language class.
You can extend the native CI_Controller class. Extending this class allows you to add your additional functionality, while the original functionality of the native core class remains.
For the code to run first on all pages, you can add your code to the constructor of the newly created subclass - if you extend your controller(s) with the new subclass, then this code will be run when any function in your controller(s) is called. To do this:
Create a subclass
Create a file named MY_Controller.php in the application/core/ directory of your project. This new class needs to extend CI_Controller and the parent constructor. The class should look something like this:
<?php
class MY_Controller extends CI_Controller {
public function __construct()
{
parent::__construct(); //make sure you extend the parent constructor
//Your code:
if( ! $this->session->userdata('lang') )
$this->session->set_userdata('lang','ar');
}
}
Ensure the class prefix is correct
If you've used MY_ as the prefix for the new class then you shouldn't need to do anything here, but it's useful to know anyway.
You'll also need to ensure that the sub-class prefix is set correctly in the application/config/config.php file.
$config['subclass_prefix'] = 'MY_';
This prefix must match the prefix of the new class that you create. By default it is MY_ but you can change it to what you want as long as they correspond - FOO_, BAR_, WHATEVER_... The exception is CI_, which is reserved for CodeIgniter's native libraries.
Extend all of you application's controller with the new subclass
Your controller(s) in application/controllers/ is(/are) probably extending CI_Controller. To make use of the newly created subclass, your controller should extend MY_Controller and the parent constructor.
class Welcome extends MY_Controller {
function __construct()
{
parent::__construct();
}
//More functions...
}

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