Laravel controller parameter's purpose? - php

namespace App\Http\Controllers;
use App\User;
use App\Http\Controllers\Controller;
class UserController extends Controller
{
/**
* Show the profile for the given user.
*
* #param int $id
* #return Response
*/
public function showProfile($id)
{
return view('user.profile', ['user' => User::findOrFail($id)]);
}
}
Why do we put parameters on laravel controllers when we can use "Input::get(id)"?
Can anyone give a sample on a situation where I need to use parameters on controller?

In your condition when you are using Input::get('id'), the request to show the profile will be something like
yourdomain.com/profile?id=2
But if you want to show the profile of a user based on something like this one,
yourdomain.com/profile/2
or
yourdomain.com/profile/john
you need a controller parameter.
In the seconds cases you can simply then, bind your parameter to the User model.
public function showProfile(User $user)
{
return view('user.profile', ['user' => $user);
}

Related

Laravel Virgin: Inject a Model In Controller as Dependency

In my inherited code in the Models there's some serious logic and I want to use the Laravel's Dependency Injection in order to load the models as Dependencies into the controller instead of Using the Laravel's provided Facades.
So here's a sample Controller:
namespace App\Http\Controllers;
use App\User;
use App\Http\Controllers\Controller;
class UserController extends Controller
{
/**
* Show the profile for the given user.
*
* #param int $id
* #return View
*/
public function show($id)
{
return view('user.profile', ['user' => User::findOrFail($id)]);
}
}
But Instead of using the Facade User I want to be able to load it as dependency into the controller:
namespace App\Http\Controllers;
use App\User;
use App\Http\Controllers\Controller;
user App\Models\User
class UserController extends Controller
{
/**
* #var User
*/
private $user=null;
public function __construct(User $user)
{
$this->user=$user;
}
/**
* Show the profile for the given user.
*
* #param int $id
* #return View
*/
public function show($id)
{
return view('user.profile', ['user' => $this->user->findOrFail($id)]);
}
}
The reason why I want to do that is because I come from Symfony Background where the Dependency Injection Pattern Is heavily Erdosed. Also Dependency Injection is the Unit Test's best buddy, so I want to be able to unitilize the Dependency Injection that I am familiar with.
So I wanted to know whether I can inject the models where the logic exists in the Controllers Instead of using the Facade Pattern provided by laravel.
When you register your route, you can use the model binding:
// routes/web.php
Route::get('users/{user}', 'UserController#show');
Then in your controller, you can change your method to:
public function show(User $user)
{
//
}
Where the $user will be the instance of App\User with the right id. For example, if the url is /users/1, the $user will contain the App\User with id 1.
For more information: https://laravel.com/docs/5.8/routing#route-model-binding

Extending Laravel base controller

I am a newbie in Laravel framework and I want to extend a base controller which in turn extends controller. However, I discovered that when I do that, my controller no longer recognises my session variables.
Here is my code
namespace App\Http\Controllers\Settings;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Http\Controllers\Auth\PermissionController;
use App\Fee;
class FeeController extends PermissionController
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index(Request $request)
{
dd(session('userdata')['user_urls']);
$data['title']="Fees";
$data['fees']=Fee::all();
return view('settings.fee.index',$data);
}
And this is my PermissionController code
<?php
namespace App\Http\Controllers\Auth;
use Illuminate\Support\Facades\Gate;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class PermissionController extends Controller {
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct(Request $request) {
if(!session('userdata')['user_urls']->contains($request->path())){
dd(session('userdata')['user_urls']);
}
}
}
But I realize that my session('userdata')['user_urls'] becomes null at the PermissionController. But if I make FeeController to extend Controller, my session variables are intact.
I need to use the session variables for some control at the permission controller.
I am running Laravel 5.3 on a MAC OSX and PHP 7
I have figured out the problem. Actually, PermissionController is not registered in the web middleware group so that session is not persisting in the PermissionController. So the solution to your question is just make a trait named as Permission instead of the controller and use it in FeesContorller.
trait Permission{
public function permission(Request $request) {
if($request->session()->get('name') != null){
echo "Hello World";
}
}
}
And FeesController like this:
class FeesController extends Controller
{
use Permission;
public function index(Request $request)
{
$this->permission($request); // the method of the trait.
echo "\n".$request->session()->get('name');
}
}
Output:
If the name attribute is set in session then :
Hello World
Passion Infinite
Otherwise
No Output // null
I have solved the same problem with middleware. I have created a middleware that takes care of the authorization of requests by checking the session to ensure that the controller action being accessed is available in session.
This is the middleware
namespace App\Http\Middleware;
use Closure;
class PermissionMiddleware
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
$currentAction = \Route::currentRouteAction();
list($nothing,$route_action) = explode('App\Http\Controllers\\', $currentAction);
$user_actions=session('userdata')['user_urls'];
if((empty($user_actions))||!$user_actions->contains($route_action)){
return redirect('denied');
}
return $next($request);
}
}
This is the controller
namespace App\Http\Controllers\Settings;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Http\Controllers\Auth\PermissionController;
use App\Fee;
class FeeController extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index(Request $request)
{
$data['title']="Fees";
$data['fees']=Fee::all();
return view('settings.fee.index',$data);
}
/**
* Show the form for creating a new resource.
*
* #return \Illuminate\Http\Response
*/
public function create(Request $request)
{
$data['title']='New Fee';
return view('settings.fee.create',$data);
}
So, instead of using the routes (cos of some other reasons), I used the controller actions.
So, once a user logs in, all the controller actions he can access are loaded into session. When he tries to perform any action, the middleware, does the check to ensure he is allowed to perform that action. Otherwise, he is routed away.
So, I either add 'permission' to the routes middleware or call
$this->middleware('permission')
on the controller's construct method.
That is working for me now.
Thank you everybody for your contributions.

How to validate in model in Laravel 5?

I am new to Laravel. Now I am starting to develop a project using Laravel 5. I have been using CodeIgniter before. I am having problem with validation class that is not compatible with what I want to do.
Normally we validate in Controller like this.
public function postCreate(Request $request)
{
$this->validate($request, [
'name' => 'required|max:30',
'mm_name' => 'required|max:50',
]);
echo "passed";
}
That is working find. But what I want to do is I want to move that validation logic to model. So I created a new folder called Models under app folder. Under the Models folder I created a class called ValidationHelper that extends the Model class.
This is my Validation helper class
<?php namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use DB;
class ValidationHelper extends Model{
function CreateCategory($request)
{
$this->validate($request, [
'name' => 'required|max:30',
'mm_name' => 'required|max:50',
]);
}
}
So now I am trying to import that class to my controller using constructor dependency injection. So now my controller is like this.
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use App\Models\ValidationHelper;
class CategoryController extends Controller
{
protected $validationHelper;
function __construct(ValidationHelper $v_helper)
{
$this->validationHelper = $v_helper;
}
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function categoryList()
{
//
return View('admin.Category.list');
}
/**
* Show the form for creating a new resource.
*
* #return \Illuminate\Http\Response
*/
public function create()
{
//
return View('admin.Category.create');
}
}
So when I run my app and do validation, it is giving me this error. How can I do this in Laravel? How to separate my validation logic to model?
You can move the code in your model by registering model event(s) as given below:
// For example, User.php model
public static function boot()
{
parent::boot();
static::creating(function($user)
{
if (!$user->isValid()) return false;
}
}
If you put this boot method in your User.php model then whenever you'll create a new user, the validation will take place at first. For this, you have to create the isValid method in your model where you'll check the validation by yourself and return true/false depending on the validation result. If you return false, creation will be inturupted. This is just an idea but you may read more here about model events.

How to populate a DropDown in Laravel 5

I need to get the id and Name about Costumers to DropDown in Laravel5 , in Laravel4 I use the following code.
public function create()
{
$data = ['groups' => Cliente::lists('name', 'id')];
return view('projects.create')->with('data',$data);
}
After , In the View I show with the following
{{ Form::select('group', $groups) }}
But in the controller Client I have this
<?php namespace App\Http\Controllers;
use App\Project;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use App\Http\Controllers\Input;
use Illuminate\Support\Facades\Validator;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Redirect;
class ClienteController extends Controller {
/**
* Display a listing of the resource.
*
* #return Response
*/
public function index()
{
$projects = Cliente::all();
return $projects;
}
/**
* Show the form for creating a new resource.
*
* #return Response
*/
}
When I execute the view create , I can see the following error
Class 'App\Http\Controllers\Cliente' not found
Finally I use this but I need to show the name and id about client in the view not only the id, any solutions for this ?
public function create()
{
$data = ['Selecciona el ID del ususario' => \DB::table('clientes')->lists('id','id')];
return view('projects.create')->with('groups',$data);
Then , the view.
{!!Form::select('user_id', $groups) !!}

How to send data/variable from one method to another in the same controller in laravel 5?

I have 2 functions/methods in the same controller in Laravel like this..
<?php namespace App\Http\Controllers;
use App\Http\Requests;
//use App\Http\Requests\CreatRole;
use App\Http\Controllers\Controller;
use Input;
use Redirect;
use Illuminate\Http\Request;
use App\UserRole;
class UserController extends Controller {
/**
* Remove the specified resource from storage.
*
* #param int $id
* #return Response
*/
public function role()
{
return view('user.role');
}
/**
* Remove the specified resource from storage.
*
* #param int $id
* #return Response
*/
public function roleProcess(Requests\CreatRole $request)
{
$input = Input::all();
$role = new UserRole;
$role->role_name = Input::get('role-name');
$role->role_number = Input::get('role-number');
$role->save();
//redirect to add page;
return Redirect::to('/home/role/add')->with('message','Role is added');
}
}
And My routes.php have route as
Route::get('/home/role/add','UserController#role');
What I am trying to do is adding and listing the role can be done from same view i.e on the same web page. I want to show the success message when the role is added. I think to do this we have to passes the success message from roleProcess to role but I don't know how to pass the variables or data from one method to another in laravel.
If I did not misunderstand your question.
you want the word "Role is added" to be shown in "user.role" view after the form submitted.
try to put following code inside "user.role" view
#if(Session::has('message'))
{{ Session::get('message') }}
#endif

Categories