Laravel routes: subfolders and error in RouteCollection - laravel

I have urls with subfolders:
/book/yur.voprosy/vopros-1.json
I don't count of subfolders levels which will be after /book/
My route is:
Route::get('/book/{file?}', 'BookController#index');
But if levels are more then 1 laravel returns:
NotFoundHttpException in RouteCollection.php line 161:
How to fix it?

You cannot really do that in Laravel, because the routing system expects you to define the exact "path", so, for it to work, you would have to:
Route::get('/book/{folder?}/{file?}', 'BookController#index');
Use it in your controller this way:
public function index($folder = null, $file = null) { ... }
So you can then do
Route::get('/book/{f1?}/{f2?}/{f3?}/{f4?}/{f5?}/{f6?}/{f7?}', 'BookController#index');
And in your controller use
public function index() {
$file = implode('/', func_get_args());
}
$numargs = func_num_args();
Or you can do:
Route::get('/findbook', 'BookController#index');
Then hit
https://yourdomain.com/findbook?filename=yur.voprosy/vopros-1.json
And get it within your controller using
Input::get('filename')

Related

laravel route by passing parameter got page not found

I just regular do the route with passing parameter
Route::get('cabinet', 'CabinetController#index');
Route::get('cabinet/{$id}', 'CabinetController#show');
and the controller just simple like this
class CabinetController extends Controller
{
function index()
{
$cabinets = Cabinet::all();
return view('detail', compact('cabinets'));
}
function show($id)
{
$single = Cabinet::find($id);
$cabinets = Cabinet::all();
return view('detail', compact('cabinets', 'single'));
}
}
public/cabinet/1
How come i got
Sorry, the page you are looking for could not be found.
Thank you for solve this for me
Remove the $ from route declaration:
Route::get('cabinet/{id}', 'CabinetController#show');

Laravel How to get Route Profile based on Route Name

I have this route:
Route::get('/test',['as'=>'test','custom_key'=>'custom_value','uses'=>'TestController#index'])
I've been tried to use $routeProfile=route('test');
But the result is returned url string http://domain.app/test
I need ['as'=>'test','custom_key'=>'custom_value'] so that I can get the $routeProfile['custom_key']
How can I get 'custom_value' based on route name ?
For fastest way, now I use this for my question:
function routeProfile($routeName)
{
$routes = Route::getRoutes();
foreach ($routes as $route) {
$action = $route->getAction();
if (!empty($action['as']) && $routeName == $action['as']) {
$action['methods'] = $route->methods();
$action['parameters'] = $route->parameters();
$action['parametersNames'] = $route->parametersNames();
return $action;
}
}
}
If there's any better answer, I will be appreciate it.
Thanks...
Try this:
use Illuminate\Support\Facades\Route;
$customKey = Route::current()->getAction()['custom_key'];
I believe you are looking for a way to pass variable to your route
Route::get('/test/{custom_key}',[
'uses'=>'TestController#index',
'as'=>'test'
]);
You could generate a valid URL like so using
route('test',['custom_key'=>'custom_key_vale'])
In your view:
<a href="{route('test',['custom_key'=>'custom_key_vale'])}"
In your controller method:
....
public function test(Request $request)
{
$custom_key = $request->custom_key;
}
....
You can try one of the below code:
1. Add use Illuminate\Http\Request; after namespace line code
public function welcome(Request $request)
{
$request->route()->getAction()['custom_key'];
}
2. OR with a facade
Add use Route; after namespace line code
and use below into your method
public function welcome()
{
Route::getCurrentRoute()->getAction()['custom_key'];
}
Both are tested and working fine!

How to call function in __constructor using laravel 5?

I am fetching menus from database based on user rights and displaying it to my web page but if i access any url whose access i don't have then too it opens that page.
For this i have created and called access_denied function which redirect user's home page.
I have called access_denied function from constructor of AuthController because AuthController gets loaded on each page.
I have used following code
AuthController
public function __construct()
{
$this->accessDenied();
}
public function accessDenied()
{
$url_segment1 = Request::segment(1);
$url_segment2 = Request::segment(2);
$url_segment = $url_segment1 . '/' . $url_segment2;
$user_data = Auth::user()->toArray();
$dadmin = array_keys($user_data['admin']);
//this is sample of array
// $user_data['admin'] => Array
// (
// [admin/roles] => 1
// )
if (!in_array($url_segment, $dadmin)) {
return redirect('/home');
}
}
But I am getting following error
Non-static method Illuminate\Http\Request::segment() should not be called statically, assuming $this from incompatible context
If i using incorrect process then please suggest me correct way to redirect unauthorised user on home page.
First, you should create a middleware. In a command prompt type:
php artisan make:middleware AccessDenyMiddleware
Then you go to app/Http/Middleware/AccessDenyMiddleware.php and fill in the handle function {your own code}
$url_segment1 = Request::segment(1);
$url_segment2 = Request::segment(2);
$url_segment = $url_segment1 . '/' . $url_segment2;
$user_data = Auth::user()->toArray();
$dadmin = array_keys($user_data['admin']);
//this is sample of array
// $user_data['admin'] => Array
// (
// [admin/roles] => 1
// )
if (!in_array($url_segment, $dadmin)) {
return redirect('/home');
}
But add the following line
return $next($request); // If passed, proceed with the route
Then, in a route, you should type:
Route::get('/yoururlhere', ['middleware' => 'AccessDenyMiddleware', function() { /* Put your work here */ } ]);
There are much better approaches. Like Authorisation if you are using Laravel 5.2
Or maybe change the default Authenticate middleware if you are using Laravel 5
You can use a middleware for thath https://laravel.com/docs/5.2/middleware#introduction.
php artisan make:middleware RoleRouteMiddleware
You should put thath code in the handle method of the middleware "App\Http\Middleware\RoleRouteMiddleware" and use the $request variable instead of the facade Request.
The middleware would filter earch request to your app.
Register a middleware, add it on app/Http/Kernel.php at routeMiddleware array
protected $routeMiddleware = [
....
'alias' => App\Http\Middleware\RoleRouteMiddleware::class,
];
and then use it on specific routes like this:
Route::get('admin/profile', ['middleware' => 'alias', function () {
//your code here
}]);
or in route gruoups:
Route::group(['middleware' => 'alias', function () {
//your filtered routes
}]);

Delete record error with custom method model laravel

User model
public function take($id){
return $this->find($id);
}
public function kill(){
return $this->delete();
}
Route Error 1
Route::get('delete/{userid}', function($id)
{
$user = new User;
$user->take($id); //result the content of $id
$user->kill();
});
i can't delete record with these route and only show blank page (without error).
Route errror 2
Route::get('delete/{userid}', function($id)
{
User::take($id)->kill();
});
And with above route i get error Non-static method User::take() should not be called statically
But i can delete with this route
Route::get('show/{userid}', function($id)
{
$user = new User;
$user->take($id)->kill();
});
So how to fix Route error 1, if i want to use $user-> without chain take() and kill() ? if it possible
How to fix Route error 2, if i want to use User:: , and why these error happen ?
Thanks in advance.
Try below :
Route::get('show/{$id}', function($id)
{
$user = new User;
$user->find($id)->kill();
});
I think the param accepted has to have the same things that is passed to the closure.

Laravel 4 : Route to localhost/controller/action

I'm more or less new to Laravel 4. I've never used routes before but normally what I'm used to is url/controller/action and then the backend routing for me. I've read the documentation for routes and controllers a few times as well as read through some tutorials and so, I'm trying to figure out how to get this to work without writing a route for every controller and action.
I tried something like
Route::get('{controller}/{action}', function($controller, $action = 'index'){
return $controller."#".$action;
});
Now then, I know this is wrong since it doesn't work, but what am I missing? On most tutorials and stuff I'm seeing an route for more or less every controller and action like:
Route::get('/controller/action' , 'ControllerName#Action');
Which seems silly and like a waste of time to me.
Is there anyway to achieve what I want?
If you are looking for a more automated routing, this would be the Laravel 4 way:
Route:
Route::controller('users', 'UsersController');
Controller (in this case UsersController.php):
public function getIndex()
{
// routed from GET request to /users
}
public function getProfile()
{
// routed from GET request to /users/profile
}
public function postProfile()
{
// routed from POST request to /users/profile
}
public function getPosts($id)
{
// routed from GET request to: /users/posts/42
}
As The Shift Exchange mentioned, there are some benefits to doing it the verbose way. In addition to the excellent article he linked, you can create a name for each route, for example:
Route::get("users", array(
"as"=>"dashboard",
"uses"=>"UsersController#getIndex"
));
Then when creating urls in your application, use a helper to generate a link to a named route:
$url = URL::route('dashboard');
Links are then future proofed from changes to controllers/actions.
You can also generate links directly to actions which would still work with automatic routing.
$url = URL::action('UsersController#getIndex');
app\
controllers\
Admin\
AdminController.php
IndexController.php
Route::get('/admin/{controller?}/{action?}', function($controller='Index', $action='index'){
$controller = ucfirst($controller);
$action = $action . 'Action';
return App::make("Admin\\{$controller}Controller")->$action();
});
Route::get('/{controller?}/{action?}', function($controller='Index', $action='index'){
$controller = ucfirst($controller);
$action = $action . 'Action';
return App::make("{$controller}Controller")->$action();
});
I come from .Net world and routing is typically done:
/{Controller}/{action}/{id}
Which looks like:
/Products/Show/1 OR /Products/Show/Beverages
In Laravel I accomplish this routing like so:
Route::get('/{controller?}/{action?}/{id?}', function ($controller='Home', $action='index', $id = null) {
$controller = ucfirst($controller);
return APP::make("{$controller}Controller")->$action($id);
});
The controller would look roughly like so:
class ProductsController extends BaseController {
public function Show($id) {
$products = array( 1 => array("Price" => "$600","Item" => "iPhone 6"),
2 => array("Price" => "$700", "Item" => "iPhone 6 Plus") );
if ($id == null) {
echo $products[1]["Item"];
} else {
echo $products[$id]["Item"];
}
}
}

Resources