Internal request without change the current route - laravel

How I can make a internal request without change the current route.
My routes:
Route::get('/my/action1', ['as' => 'action1', 'uses' => 'MyController#action1']);
Route::get('/my/action2', ['as' => 'action2', 'uses' => 'MyController#action2']);
My controller:
namespace App\Http\Controllers;
use Route;
use Request;
class MyController extends Controller
{
public function action1()
{
return 'action1';
}
public function action2()
{
$request = Request::create('/my/action1', 'GET');
$response = app()->handle($request);
dump(Route::getCurrentRoute()->getName()); // I need return "action2"
return $response; // I need return "action1"
}
}
When the internal request is called, the current route is changed and I don't want this effect. What I need make?

Related

Return to resource route

I have below route in my route file.
Route::group( ['prefix' => 'prayer', 'as' => 'prayer.'], function () {
Route::resource( 'time', 'PrayerTimeController' );
});
How can I return to this route from Controller ?
Firstly, I highly recommend reading through the excellent Laravel documentation: https://laravel.com/docs/9.x/controllers#resource-controllers
To get the route wired up to a controller, update your route resource declaration to use the full class name of the controller:
Route::resource('time', PrayerTimeController::class);
Create a controller file: App\Http\Controllers\PrayerTimeController.php with this content:
<?php
namespace App\Http\Controllers;
class PrayerTimeController extends Controller
{
public function index()
{
return 'Hello, World!';
}
}
Then import the controller namespace into the routes file you're working in, e.g. routes/web.php file:
use App\Http\Controllers\PrayerTimeController;
Route::group(['prefix' => 'prayer', 'as' => 'prayer.'], function () {
Route::resource('time', PrayerTimeController::class);
});

How make Route::resource with page and filter options?

In Laravel 5.8 making backend rest api app with resource defined in routes/api.php, as
Route::group(['middleware' => 'jwt.auth', 'prefix' => 'adminarea', 'as' => 'adminarea.'], function ($router) {
...
Route::resource('skills', 'API\Admin\SkillController');
now on clients part for listing of skills I need to add current_page and filter_name.
Can it be done with Route::resource definition ?
Actually when we making the resource controller in laravel then it created the method index
create,
store,
show,
edit,
update,
destroy.
method and routes of these respectively but when you are going to define the new method and for access this method then you need to create new route for this.
otherwise it is not possible with the resource route in laravel.
public function abc(Request $request)
{
dd($request->all());
}
route for this
route::post('/abc','ABCController#abc')->name('abc');
you can check the route by this command
php artisan route:list or
php artisan r:l
hope you understand.
After some search I found a decision in defining in routes one more post route:
Route::group(['middleware' => 'jwt.auth', 'prefix' => 'adminarea', 'as' => 'adminarea.'], function ($router) {
Route::post('skills-filter', 'API\Admin\SkillController#filter');
Route::resource('skills', 'API\Admin\SkillController');
...
and in app/Http/Controllers/API/Admin/SkillController.php :
<?php
namespace App\Http\Controllers\API\Admin;
use Auth;
use DB;
use Validator;
use App\User;
use App\Http\Resources\Admin\Skill as SkillResource;
class SkillController extends Controller
{
private $requestData;
private $page;
private $filter_name;
private $order_by;
private $order_direction;
public function __construct()
{
$this->middleware('jwt.auth', ['except' => []]);
$request = request();
$this->requestData = $request->all();
}
public function filter()
{
if ( ! $this->checkUsersGroups([ACCESS_ROLE_ADMIN])) {
return response()->json(['error' => 'Unauthorized'], 401);
}
$backend_items_per_page = Settings::getValue('backend_items_per_page');
$this->page = !empty($this->requestData['page']) ? $this->requestData['page'] : '';
$this->filter_name = !empty($this->requestData['filter_name']) ? $this->requestData['filter_name'] : '';
$this->order_by = !empty($this->requestData['order_by']) ? $this->requestData['order_by'] : 'name';
$this->order_direction = !empty($this->requestData['order_direction']) ? $this->requestData['order_direction'] : 'asc';
$this->index();
$skills = Skill
::getByName($this->filter_name)
->orderBy($this->order_by, $this->order_direction)
->paginate($backend_items_per_page);
return SkillResource::collection($skills);
} // public function filter()
public function index()
{
if ( ! $this->checkUsersGroups([ACCESS_ROLE_ADMIN])) {
return response()->json(['error' => 'Unauthorized'], 401);
}
$backend_items_per_page = Settings::getValue('backend_items_per_page');
$skills = Skill::paginate($backend_items_per_page);
return SkillResource::collection($skills);
}
As that is adminarea some filter actions can have more 1 filter...
Just interested to know which other decisions are possible here?

Laravel Route Always Goes to index

In my Laravel application, I store a new user via Ajax to the DB. The app always calls the index method. What's wrong?
When I remove the Route::post('/users', 'Admin\UserController#store'); route there is a 405 error. That's correct. But why doesn't it go to the store method?
Controller
<?php
class UserController extends Controller
{
public function index()
{
return view('admin.user.index');
}
public function create()
{
//
}
public function store(UserCreateRequest $request)
{
$user = User::createFromRequest($request);
return response()->json(["id" => $user->id]);
}
}
Routes
Route::group(['prefix' => 'admin', 'as' => 'admin.', ], function () {
Route::get('/users/{user}', 'Admin\UserController#show')->name('users.show');
Route::post('/users', 'Admin\UserController#store');
Route::put('/users/{id}', 'Admin\UserController#updateFromDatatable');
Route::delete('/users/{id}', 'Admin\UserController#destroy');
Route::get('/users', 'Admin\UserController#index')->name('users.index');

laravel UserRequest $request error

laravel5.2,I create a UserRequest.php under Requests directory,but in controller,public function add(UserRequest $request) show error,but use public function add(Request $request) is normal.
UserRequest
namespace App\Http\Requests;
use App\Http\Requests\Request;
class UserRequest extends Request
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'user_sn' => 'required|unique',
'user_name' => 'required',
'email' => 'required|unique',
'password' => 'required',
];
}
}
UserController
namespace App\Http\Controllers;
use App\Http\Requests\UserRequest;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
class UserController extends Controller
{
public function add(UserRequest $request)
{
if ($request->get('dosubmit')) {
$validator = Validator::make($request->all(), $request
->rules(), $request->messages());
if ($validator->fails()) {
return redirect('user/add')->withErrors($validator)
->withInput();
}
}
$corporation_list = DB::table('corporation')->get();
$department_list = DB::table('department')->get();
return view('user.add', ['corporation_list' => $corporation_list, 'department_list' => $department_list]);
}
}
Route
Route::group(['middleware'],function (){
Route::any('user/add',['as'=>'user.add','uses'=>'UserController#add']);
});
There are usually 2 reasons you could be having this issue.
You've not added the use statement for the UserRequest.
At the top of your controller (above the class) add:
use App\Http\Requests\UserRequest
assuming that is the correct namespace.
You may need to run composer dump-autoload to make sure the class has been added to the autoloader.
Edit
Firstly, replace the add() method with the following methods:
public function create()
{
$corporation_list = DB::table('corporation')->get();
$department_list = DB::table('department')->get();
return view('user.add', compact('corporation_list', 'department_list'));
}
public function store(UserRequest $request)
{
// If you get to this point the validation will have passed
// Process the request
}
Then change your routes from:
Route::any('user/add',['as'=>'user.add','uses'=>'UserControl‌​ler#add'])
to:
Route::get('user/add', ['as' => 'user.add', 'uses' => 'UserControl‌​ler#create']);
Route::post('user/add', ['as' => 'user.store', 'uses' => 'UserControl‌​ler#store']);
Obviously, feel free to change the as in the Routes to whatever, they should unique though.
Lastly, I would suggest looking at Resource Controllers which is a RESTful approach.
The problem is that you have not identified UserController that you are using UserRequest file
use App\Http\Requests\UserRequest
It will solve the problem

Extend Resource Controllers

I'm doing what I want in a certain way and I'm looking for alternatives or better ways of doing.
I'm using Resource Controllers in my application. Also I'm using softdelete in several models, so my routes are as follows:
Route::get('users/deleted', array('uses' => 'UserController#trash'));
Route::put('users/{id}/restore', array('uses' => 'UserController#restore'));
Route::resource('users', 'UserController');
The first route is to display objects that have been deleted.
The second allows me to restore these deleted elements.
The third maps the traditional methods (create, edit, update, etc.).
I have several controllers that work exactly the same way, I wonder if have any way to tell laravel to work with this two methods (trash and delete) by default without the two extra lines.
Is it possible? Or to give a better way that I'm doing?
(sorry for bad english)
Keeping things simple and DRY.
You can extend the Router and replace the Route Facade in your app/config/app.php file but seems like a lot of work for not much gain, but don't forget that your routes file is a PHP script and you can do things like:
$routes = [
['users' => 'UserController'],
['posts' => 'PostController'],
];
foreach ($routes as $key => $controller)
{
Route::get("$key/deleted", array('uses' => "$controller#trash"));
Route::put("$key/{id}/restore", array('uses' => "$controller#restore"));
Route::resource($key, $controller);
}
Extending the router
To extend the router you need to create 3 classes:
The Router extended, where you'll add your new methods:
<?php namespace App\Routing;
class ExtendedRouter extends \Illuminate\Routing\Router {
protected $resourceDefaults = array(
'index',
'create',
'store',
'show',
'edit',
'update',
'destroy',
'deleted',
'restore',
);
protected function addResourceDeleted($name, $base, $controller)
{
$uri = $this->getResourceUri($name).'/deleted';
return $this->get($uri, $this->getResourceAction($name, $controller, 'deleted'));
}
protected function addResourceRestore($name, $base, $controller)
{
$uri = $this->getResourceUri($name).'/{resource}/restore';
return $this->get($uri, $this->getResourceAction($name, $controller, 'restore'));
}
}
A Service Provider, to boot your new router, using the same IoC identifier Laravel uses ('router'):
<?php namespace App\Routing;
use Illuminate\Support\ServiceProvider;
class ExtendedRouterServiceProvider extends ServiceProvider {
protected $defer = true;
public function register()
{
$this->app['router'] = $this->app->share(function() { return new ExtendedRouter($this->app); });
}
public function provides()
{
return array('router');
}
}
And a Facade, to replace Laravel's one
<?php namespace App\Facades;
use Illuminate\Support\Facades\Facade as IlluminateFacade;
class ExtendedRouteFacade extends IlluminateFacade {
public static function is($name)
{
return static::$app['router']->currentRouteNamed($name);
}
public static function uses($action)
{
return static::$app['router']->currentRouteUses($action);
}
protected static function getFacadeAccessor() { return 'router'; }
}
Then you need to add your Service Provider and Facade to your app/config/app.php file, commenting the Laravel original ones.
Im using route model bind.
I do this way.
<?php
namespace App\Http\Router;
use Illuminate\Support\Facades\Route;
use Illuminate\Routing\Router;
class CustomRouter extends Router
{
public function customResource($routeName, $controllerPath, $routeBindName = null, $routeBindModel = null) {
$routeBindName = $routeBindName ?? $routeName;
$routeBindNameTrashed = "{$routeBindName}_trashed";
if($routeBindModel && $routeBindName) {
Route::model($routeBindName, $routeBindModel);
Route::bind($routeBindNameTrashed, function($modelId) use ($routeBindModel) {
return app($routeBindModel)->newQuery()->onlyTrashed()->findOrFail($modelId);
});
}
Route::put("$routeName/{{$routeBindNameTrashed}}/restore", "{$controllerPath}#restore")->name("{$routeName}.restore");
Route::delete("$routeName/{{$routeBindNameTrashed}}/force", "{$controllerPath}#forceDelete")->name("{$routeName}.force-delete");
Route::resource($routeName, $controllerPath);
}
}
Alter bootstrap/app.php
$app->singleton(
'router',
App\Http\Router\CustomRouter::class
);
Then usage:
Route::customResource('projects', 'ProjectsController', 'project', \App\Models\Project::class);
Route:list
Works like a charm
$routes = [
'posts' => 'PostController',
'posts.comments' => 'PostCommentController',
];
foreach ($routes as $key => $controller)
{
Route::get("$key/deleted", array('uses' => "$controller#trash"));
Route::put("$key/{id}/restore", array('uses' => "$controller#restore"));
Route::resource($key, $controller);
}

Resources