Unused parameters in routes Laravel 5.1 - laravel

I write api for mobile, since I have more than one version, I don't want to copy-paste the same routes, hence I decided to do something like this:
Route::model('callRequestNote', CallRequestNote::class);
Route::group([
'prefix' => 'api/v{version}/mobile',
'where' => ['version' => '[1|2]'],
], function () {
Route::delete('/notes/{callRequestNote}', MobileNotesController::class . '#destroy');
// other duplicated routes
});
public function destroy($version, CallRequestNote $callRequestNote)
{
//
}
I use version parameter only in BeforeMiddleware, hence I don't need it in controller. My question is how to replace those parameters and make CallRequestNote as a first argument and get rid of $version?

Related

Backpack 4.1 Routes syntax

I'm updating Laravel 5.4 to Laravel 8, so far everything goes "well" it's time consuming but the upgrade worth it.
My problem is that I don't know Backpack very well and the upgrade is considerable.
I'm now stuck with the new route syntax, there where a CRUD::resource facade that handled route customization that is not available anymore.
What would be the right approach for the following "simplified" custom route files. (I removed everything I figured already)
Route::group([
'prefix' => config('backpack.base.route_prefix', 'admin'),
'middleware' => [
'web',
config('backpack.base.middleware_key', 'admin'),
],
'namespace' => 'App\Http\Controllers\Admin',
], function() { // custom admin routes
Route::get('report', function() {
$clients = ClientWithSubscription::get();
$clientsT = transformer()->transform($clients);
return view('clients')->withClients($clientsT['data']);
});
// Client
CRUD::resource('client', 'ClientCrudController');
Route::group(['prefix' => 'client/{client_id}'], function() {
CRUD::resource('address', 'ClientAddressCrudController');
CRUD::resource('subscription', 'ClientSubscriptionCrudController');
});
// Taxonomy
foreach (['theme', 'tag', 'subject', 'utility', 'document_type', 'special_need', 'level', 'platform', 'other', 'shop',] as $taxonomy) {
CRUD::resource('taxonomy/' . $taxonomy, 'TaxonomyCrudController');
}
// Items
CRUD::resource('item/document', 'ItemDocumentCrudController');
// Referrals
CRUD::resource('referrals', 'ReferralCrudController')->with(function() {
Route::post('referrals/mark-paid/{id?}', 'ReferralCrudController#markPaid');
Route::post('referrals/mark-unpaid/{id?}', 'ReferralCrudController#markUnpaid');
Route::post('referrals/edit-notes/{id}', 'ReferralCrudController#editNotes');
});
});
My questions are
How do I add a prefix to all crud route ?
If a CrudController use default route, then it mean I don't need to declare it at all, Backpack will take care of it ?
How do I add custom method to the CRUD Route ?
Thank you!
Two changes are needed:
instead of CRUD::resource('item/document', 'ItemDocumentCrudController'); you should now do Route::crud('item/document', 'ItemDocumentCrudController');
the extra routes inside the ->with() closures should be moved after the appropriate Route::crud() statement;
See this step in the Backpack upgrade process for more details.
Also, make sure to upgrade to Backpack 4.0 (using its upgrade guide), and only after it's working to upgrade to Backpack 4.1 (the latest version).

Localization in laravel

I designed a site with Laravel. now I want add new language to it.I read laravel document . It was good but I have a problem.suppose I have a page that show detail of products so I have a route like mysite.com/product/id that get product's id and show it.also I have a method in controller like
public function showProduct($id){
...
}
If I add new Language , the route will change to this: mysite/en/product/id
now I must change my method because now two parameter send my method.something like this :
public function showProduct($lang,$id){
...
}
So two problems arise:
I must change all method in my site which is time consuming
I do not need language parameter in methods because I set $locan via middleware
pay attention that I do not want remove for example en from my URL (because of SEO)
Open your RouteServiceProvider and say that language parameter actually is not a parameter, it's a global prefix.
protected function mapWebRoutes()
{
Route::group([
'middleware' => 'web',
'namespace' => $this->namespace,
'prefix' => Request::segment(1) // but also you need a middleware about that for making controls..
], function ($router) {
require base_path('routes/web.php');
});
}
here is sample language middleware, but it's need to be improve
public function handle($request, Closure $next)
{
$langSegment = $request->segment(1);
// no need for admin side right ?
if ($langSegment === "admin")
return $next($request);
// if it's home page, get language but if it's not supported, then fallback locale gonna run
if (is_null($langSegment)) {
app()->setLocale($request->getPreferredLanguage((config("app.locales"))));
return $next($request);
}
// if first segment is language parameter then go on
if (strlen($langSegment) == 2)
return $next($request);
else
// if it's not, then you may want to add locale language parameter or you may want to abort 404
return redirect(url(config("app.locale") . "/" . implode($request->segments())));
}
So in your controller, or in your routes. you don't have deal with language parameter
Something like
Route::group(['prefix' => 'en'], function () {
App::setLocale('en');
//Same routes pointing to the same methods...
});
Or
Route::group(['prefix' => 'en', 'middleware' => 'yourMiddleware'], function () {
//Same routes pointing to the same methods...
});

How to use multiple method in single route in laravel

I want to use more than one method in a single route using laravel. I'm try this way but when i dd() it's show the plan string.
Route::get('/user',[
'uses' => 'AppController#user',
'as' => 'useraccess',
'roles'=> 'HomeController#useroles',
]);
When i dd() 'roles' option it's show the plan string like this.
"roles" => "HomeController#useroles"
my middleware check the role this way.
$actions=$request->route()->getAction();
$roles=isset($actions['roles'])? $actions['roles'] : null;
The simplest way to accept multiple HTTP methods in a single route is to use the match method, like so:
Route::match(['get', 'post'], '/user', [
'uses' => 'AppController#user',
'as' => 'useraccess',
'roles'=> 'HomeController#useroles',
]);
As for your middleware, to check the HTTP request type, a tidier way would be:
$method = request()->method();
And if you need to check for a specific method:
if (request()->isMethod('post')) {
// do stuff for post methods
}
Here's how you can do multiple methods on a single route:
Route::get('/route', 'RouteController#index');
Route::post('/route', 'RouteController#create');
Route::put('/route', 'RouteController#update');
/* Would be easier to use
* Route::put('/route/{route}', 'RouteController#update');
* Since Laravel gives you the Model of the primary key you've passed
* in to the route.
*/
Route::delete('/route', 'RouteController#destroy');
If you've written your own middleware, you can wrap the routes in a Route::group and apply your middleware to those routes, or individual routes respectively.
Route::middleware(['myMiddleware'])->group(function () {
Route::get('/route', 'RouteController#index');
Route::post('/route', 'RouteController#create');
Route::put('/route', 'RouteController#update');
});
Or
Route::group(['middleware' => 'myMiddleware'], function() {
Route::get('/route', 'RouteController#index');
Route::post('/route', 'RouteController#create');
Route::put('/route', 'RouteController#update');
});
Whichever is easier for you to read.
https://laravel.com/docs/5.6/routing#route-groups

Laravel optional prefix routes with regexp

Is there a way to create routes with prefixes so I can have routes like this
/articles.html -> goes to listing Controller in default language
/en/articles.html -> goes to the same controller
/fr/articles.html -> goes to the same controller
My current problem is that by doing:
Route::group(['prefix=>'/{$lang?}/',function(){});
a route like this: /authors/author-100.html will match a prefix 'authors` , and for sure there is no language called "authors".
I use laravel 5.5
There doesn't seem to be any good way to have optional prefixes as the group prefix approach with an "optional" regex marker doesn't work. However it is possible to declare a Closure with all your routes and add that once with the prefix and once without:
$optionalLanguageRoutes = function() {
// add routes here
}
// Add routes with lang-prefix
Route::group(
['prefix' => '/{lang}/', 'where' => ['lang' => 'fr|en']],
$optionalLanguageRoutes
);
// Add routes without prefix
$optionalLanguageRoutes();
This should be sufficient using the where Regex match on the optional route parameter:
Route::get('/{lang?}, 'SameController#doMagic')->where('lang', 'en|fr');
You can do the same on Route Group as well, else having all the options as in this answer evidently works.
An update to show the use of prefix:
Route::group(['prefix' => '{lang?}', 'where' => ['lang' => 'en|fr']],function (){
Route::get('', 'SameController#doNinja');
});
As far as I am concerned this should be sufficient even when there is no lang as well as when there is one, just maybe this group could come before other routes.
You can use a table to define the accepted languages and then:
Route::group([
'prefix' => '/{lang?}',
'where' => ['lang' => 'exists:languages,short_name'],
], function() {
// Define Routes Here
});
Another working solution would be to create an array of langs and loop over it:
$langs = ['en', 'fr', ''];
foreach($langs as $lang) {
Route::get($lang . "/articles", "SomeController#someMethod");
}
For sure this makes your route file less readable, however you may use php artisan route:list to clearly list your routes.

How to add dynamically prefix to routes?

In session i set default language code for example de. And now i want that in link i have something like this: www.something.com/de/something.
Problem is that i cant access session in routes. Any suggestion how can i do this?
$langs = Languages::getLangCode();
if (in_array($lang, $langs)) {
Session::put('locale', $lang);
return redirect::back();
}
return;
Route::get('blog/articles', 'StandardUser\UserBlogController#AllArticles');
So i need to pass to route as prefix this locale session.
If you want to generate a link to your routes with the code of the current language, then you need to create routes group with a dynamic prefix like this:
Example in Laravel 5.7:
Route::prefix(app()->getLocale())->group(function () {
Route::get('/', function () {
return route('index');
})->name('index');
Route::get('/post/{id}', function ($id) {
return route('post', ['id' => $id]);
})->name('post');
});
When you use named routes, URLs to route with current language code will be automatically generated.
Example links:
http://website.com/en/
http://website.com/en/post/16
Note: Instead of laravel app()->getLocale() method you can use your own Languages::getLangCode() method.
If you have more questions about this topic then let me know about it.
Maybe
Route::group([
'prefix' => Languages::getLangCode()
], function () {
Route::get('/', ['as' => 'main', 'uses' => 'IndexController#index']);
});

Resources