Using controller in view with Laravel - php

I have simple function in one of my controller (members):
function action_data($array) {
$datamembre = DB::table('members')->where('id', '=', $id)->first();
return $datamembre;
}
I want use it in the view of another controller, I do this in my template:
$datamembers = Controller::call('members#data', array($members_id));
Is there any better or proper way to do it?

The best would be to put it into a Member model IMO.

Use view composer http://laravel.com/docs/views#view-composers
View::composer(array('home', 'profile'), function($view)
{
//
});
update
You can put the method in BaseController, all controllers extend it, so you could get this method in any controller/view. And make it static.
// in BaseController.php (L4) or Base.php (L3)
static public function action_data($array) {
$datamembre = DB::table('members')->where('id', '=', $id)->first();
return $datamembre;
}
In the view
BaseController::action_data($array); //L4
Base_Cotroller::action_data($array); //L3
Hope it works. Haven't tested it.

Related

How to pass data to multiple blades in laravel and with a single route

i have tried to passing data to multiple blade in controller but get error. Here bellow my code
public function index()
{
$news = DB::table('beritas')
->select('id','judul_berita','created_at')
->get();
return view (['berita.daftar-berita', 'more-menu.berita'])->with(compact('news'));
}
How to pass data to multiple blades in laravel and with a single route?
If u want pass data to multiple blades u can share it in the Constructor like so:
public function __construct(){
$this->middleware(function ($request, $next) {
$news = DB::table('beritas')>select('id','judul_berita','created_at')->get();
View::share('news', $news);
return $next($request);
});
}
and now u can use news variable in all you blades that using the same controller.
i hope it's will help you
Probably the right place to this is in the boot method of some service provider, for example, AppServiceProvide.
//AppServiceProvider.php
public function boot()
{
view()->share('someVariable',$someVariable);
}
This will make someVariable available to all of blade views. This is useful for template level variables.

Call controller function in another controller

I've a PermissionController with a permission() function like below, and i want to call the permission() function in another controller. How can i call my permission() function to another controller ?
here my PermissionController
class PermissionController extends Controller
{
public function permission(){
$checkPermission = User::leftJoin('employees', 'employees.user_id', '=', 'users.id')
->leftJoin('positions', 'employees.position_id', '=', 'positions.id')
->leftJoin('divisions', 'employees.division_id', '=', 'divisions.id')
->where(function($query){
$query->where('division_name', 'Sales')
->orWhere('division_name', '=', 'Project Management')
->orWhere('position_name', '=', 'Dept Head');
})
->get();
}
}
Create new Helper (e.g PermissionHelper.php) then move the funtion to it and call it where you want using :
PermissionHelper::permission();
Hope this helps.
You can call another controller's method, but this is terrible practice. Move you code to a model and call it with:
class PermissionController extends Controller
{
public function permission()
{
$checkPermission = User::getEmployeePermissions();
}
}
Do the same in other controllers' methods.
I think your function should be in one of your model since you're only getting value.
This will me more relevant according to MVC.
Having it in your User model will let you use it on every instance of your application with a single call.
You can call your PermissionController's "permission" method this way :
app(PermissionController::class)->permission();
However, be aware that this method isn't a good idea at all.
You have multiple refactoring options available ranging from the use of a helper class, a method on the concerned model or using a laravel job.
Try to do like this
public function __construct(PermissionController $permission_controller)
{
parent::__construct();
$this->permission_controller = $permission_controller;
}
Call any method like this
$this->permission_controller->permission();

Laravel: How to set $id to Auth::user()->id; in resource controller methods

I have Laravel's built in auth working. Users can register and login.
What I'd like to do is set the $id parameter for the UserController's show() method with the value from Auth::user()->id;
My thoughts behind this is, to not have to use id's in the routes.
I'm pretty new to OOP, and php in general, so I'm not sure how to tackle this.
Thanks in advance for any tips or help!
1st method
You can have a route with an optional user id:
Route::get('user/show/{id?}', 'UsersController#show')
If the show method of your controller doesn't get an id, it can use Auth::user() instead:
class UsersController extends BaseController {
public function show($id = null)
{
return View::make('userProfile')->with('user', $this->getCurrentUser($id));
}
public function getCurrentUser($id)
{
$this->currentUser = $id ? User::find($id) : Auth::user();
}
}
Then in your view you will be able to always
{{ $user->name }}
2nd method
You could also have a BaseController which does that automatically for you using View::share():
class BaseController extends Controller {
public function __construct()
{
parent::__construct();
$this->shareUser();
}
public function shareUser($id = null)
{
View::share('user', $id ? User::find($id) : Auth::user());
}
}
Then in your controller you don't need to pass the user:
class UsersController extends BaseController {
public function show()
{
return View::make('userProfile');
}
public function thisIsAMethodOverridingIt($id)
{
$this->shareUser($id);
return View::make('userProfile');
}
}
It would even better to have this provided by a Service, but you'll have to read about Service Providers and Facades to make it happen.
And you are still able to do that:
{{ $user->name }}
Because View::share() will send that variable to all your views.
3rd method
If you just need your user everywhere, use a global View::composer():
View::composer('*', function($view)
{
$view->with('currentUserName', Auth::check() ? Auth::user()->firstname : '');
});
You can put this in your routes.php or, better create a file for this purpose, something like app/composers.php and load it in your app/start/global.php:
require app_path().'/composers.php';
As always, you can use it in your view, this way:
{{ $user->currentUserName }}
If you just need it for a couple of views, you can
View::composer(array('profile','dashboard'), function($view)
{
$view->with('currentUserName', Auth::check() ? Auth::user()->firstname : '');
});
This is actually a recent problem that I encountered while working on an API.
The way I handled it, was to introduce /me endpoints, so for example, you'd have:
Route::group(['before' => 'auth'], function() {
Route::get('/user/show/{id}', 'UsersController#show');
Route::get('/me', 'UsersController#show');
}
You'll notice that both routes point to the same code, but have different addresses. This means that you can simplify requests by using the /me convention, without having to duplicate code. You'll also notice that I enclosed these in a group which applies the auth filter. This basically just makes sure that the user is authed, and while it may not be required for the first one, it'd definitely be required for the second.
Then your show method would look like this:
public function show($id = false)
{
$user = $this->getUserOrMe($id);
return View::make('myview', ['user' => $user]);
}
This would require the below function:
private function getUserOrme($id)
{
return $id !== false ? User::find($id) : Auth::user();
}
A controllers methods should be accessed independently of each other, meaning that once the User object is returned, all the relevant code for the current request has access to it. Storing the User object in a class property would just over engineering.
Hope that helps.

Laravel 4.1 - Controller throw error when I try to load view with layout

I'm trying to load a blade view with layout, but I get this error:
"Attempt to assign property of non-object"
The structure is the following:
Route:
Route::pattern('controller', '\w+');
Route::get('{controller}', function($controller) {
$controllerClass = $controller.'Controller';
App::make($controllerClass)->index();
});
Controller:
class PricesController extends BaseController {
protected $layout = 'layouts.master';
public function index()
{
$this->layout->content = View::make('prices.index');
}
}
The debug says the issue is at line $this->layout->content = View::make('prices.index');
The views are fine... I have layouts folder with master.blade.php and I also have prices folder with index.blade.php.
The content section is exists as well with #stop and the #yield is there in the layout.
In the BaseController there is the setupLayout method:
protected function setupLayout()
{
if ( ! is_null($this->layout))
{
$this->layout = View::make($this->layout);
}
}
What is the problem? Why I get that exception?
Thank you!
I know I helped you in the #laravel irc channel but there are 3 things here for any others with this problem.
This is not a good use of route files. Controller implicit routing is hard to maintain if your app gets larger. Consider using Route::resource instead if you're just trying to save a few lines of code. But I'll give you the benefit of the doubt.
You'll want to use the nest method for your layout, i.e. $this->layout->nest('content', 'prices.index');
The setupLayout() function is not being called because you are calling index() directly on the object. This is not how Laravel normally processes controllers.
I'm not going to walk through the entire routing process but if you look at vendors/laravel/framework/src/Illuminate/Routing/ControllerDisplatcher.php on line 89 you will see:
protected function call($instance, $route, $method)
{
$parameters = $route->parametersWithoutNulls();
return $instance->callAction($method, $parameters);
}
Let's look at vendors/laravel/framework/src/Illuminate/Routing/Controller.php on line 227 and you will see:
public function callAction($method, $parameters)
{
$this->setupLayout();
$response = call_user_func_array(array($this, $method), $parameters);
... irrelevant stuff omitted ...
}
These reason I show these things is show the magic Laravel is doing behind the scenes.
Basically you are skipping that magic and just calling PricesController->index() directly instead of going through the router. This is why setupLayout is never being called and you will get an exception because there is no $this->layout object yet created.

Nesting controllers and views in Laravel

I have a controller in my Laravel project called ImageController. This is a pretty basic CRUD controller.
When I access /images/{id} through my ImageController#show action, I want to also display comments. However, I don't want to put the comment logic in my ImageController. For this logic, I have created an ImageCommentController.
I'm not really sure how to go about this, but I'm trying to do something of this sort:
class ImageController extends BaseController {
// methods ...
public function show($id)
{
$images = // get images ...
$this->layout->view = // images.show and imagescomment.index (using ImageCommentsController#index logic)
}
}
I'm sorry if this is vaguely phrased, let me know if it is and I'll try to make it more understandable.
Maybe a better solutions than using a Controller for displaying the comments is to use a class with a method renderComments() that basically does something like:
class Comments {
public static renderComments($commentType = 'images')
{
$comments = Comments::where('comment_type', '=', $commentType)->get();
return View::make('comments', $comments)->render();
}
}
Then for example inside your image view:
...
{{ Comments::renderComments() }}
...

Categories