(api) resource group route - laravel

When grouping routes through resources as such:
Route::resource('books/{book}/catalog', 'CatalogController', ['names' => [
'index' => 'catalog.index',
'store' => 'catalog.store',
'update' => 'catalog.update',
'destroy' => 'catalog.destroy',
], 'except' => ['create', 'edit', 'show']]);
The route:list command outputs:
DELETE | api/v1/books/{book}/catalog/{catalog}
PUT|PATCH | api/v1/books/{book}/catalog/{catalog}
However I was hoping for:
DELETE | api/v1/books/{book}/catalog
PUT|PATCH | api/v1/books/{book}/catalog
Any suggestions how I can get the results when grouping, without the extra {catalog} parameter in the DELETE and PUT|PATCH routes?

Why are you not just using the apiResource method?
It makes it all so much tidier.
Route::apiResource('catalog', 'CatalogController');

I am assuming that there is a one-to-one relationship between books and catalogs, and that is why you don't need the catalog parameter to determine which catalog to delete/update.
If this is the case, what you're looking for is singular resource routing. Laravel does not provide this by default.
I have created a package that adds this functionality to Laravel: shiftonelabs/laravel-singular-resource-routes.
One change you would need to make, however, is to change your index route to the show route. Singular resources are by definition singular, so there isn't a group of resources to index, there is only one resource to show.
After installing the package, you would update your route to include the 'singular' => true option (and change your index route):
Route::resource('books/{book}/catalog', 'CatalogController', [
'names' => [
'show' => 'catalog.show',
'store' => 'catalog.store',
'update' => 'catalog.update',
'destroy' => 'catalog.destroy',
],
'except' => ['create', 'edit'],
'singular' => true,
]);

Related

Laravel and Spatie Permissions plugin update not working

I've performed a long-overdue update on a Laravel project from v5.7 (with Spatie Permissions 2.21) to v9 with Spatie 5.5.0. I'm not getting any error but the hasRole() function no longer ever returns true for users who definitely have the role. Echoing Auth::user()->getRoleNames() for the user just returns an empty array. Any guidance would be greatly appreciated.
Looking at my old commits, it seems that aside from the composer.json additions and database migrations, that only things I needed to do were a User model edit:
...
use Spatie\Permission\Traits\HasRoles;
class User extends Authenticatable
{
use HasRoles;
...
And this config/permission.php (comments stripped):
<?php
return [
'models' => [
'permission' => Spatie\Permission\Models\Permission::class,
'role' => Spatie\Permission\Models\Role::class,
],
'table_names' => [
'roles' => 'roles',
'permissions' => 'permissions',
'model_has_permissions' => 'model_has_permissions',
'model_has_roles' => 'model_has_roles',
'role_has_permissions' => 'role_has_permissions',
],
'column_names' => [
'role_pivot_key' => null, //default 'role_id',
'permission_pivot_key' => null, //default 'permission_id',
'model_morph_key' => 'model_id',
'team_foreign_key' => 'team_id',
],
'register_permission_check_method' => true,
'teams' => false,
'display_permission_in_exception' => false,
'display_role_in_exception' => false,
'enable_wildcard_permission' => false,
'cache' => [
'expiration_time' => \DateInterval::createFromDateString('24 hours'),
'key' => 'spatie.permission.cache',
'store' => 'default',
],
];
Below few things i would like to try
$user->assignRole($this->roles)
Try echo below line just after assign
echo $user()->getRoleNames()
Also try fetch with relations
Dump($user->with('roles')->get()
It will tell you atleast roles assignment is working.
So it turns out this was connected to another problem I was having that fortunately I was trying to fix at the same time:
Laravel upgrade broke model paths
The cause of this permissions issue was in the database but not table / field names, but actually the field contents.
In the model_has_roles table, the old App\User namespace was used (hopefully I'm using "namespace" correctly there!) and should have been App\Models\User in line with the new namespace. Then it all worked fine.

How to start using Slug URLs without breaking old in Yii2

i want to rewrite my URLs from
/view?id=100
to
/view/100-article-title
But the site already has several thousand search pages. As far as I know, such a change can be bad for SEO. Is there a way to keep the old URLs working when switching to the new routing.
*I am creating links as follows:
Url::to(['view', 'id' => $item->id])
Is it possible to create links further through ID?
you can create getLink() function on your model and use it on. Then, when function runs you can check id if id <= 100 then return Url::to(['view', 'id' => $item->id]) else return Url::to(['view', 'id' => $item->id, 'slug' => $this->slug])
And add route with slug on your main.php
Look at my example.
First config urlManager in config.php in 'app/config' folder. In my case look like:
'components' => [
...
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
''=>'home/index',
'<slugm>-<id:\d+>-' => 'home/view',
],
],
.
...
],
and create link as fallow:
Url::to(['/home/view', 'id' => $model->home_id, 'slugm' =>$model->title_sr_latn])
and finaly url look like:
https://primer.izrada-sajta.rs/usluge-izrade-sajtova-1-

Change/Rename Controller Name In URL: Yii2

I was looking to change controller name in URL. Which, we can do by renaming the controller name in module. But, Through URL manager if we can do it. It will be better.
Module: user,
Controller: api,
Action: index
Right now,
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
'<controller:(api)>/<action:\w+>/<id:[a-z0-9]+>' => 'user/<controller>/<action>',
'<controller:(api)>/<action>' => 'user/<controller>/<action>',
]
];
And, I can access it through.
http://dev.example.com/api/index
But, I was looking to change it to
http://dev.example.com/world/index
How can I do it? Any help/hint/suggestion is appreciable.
You can create custom url rules by adding items to the rules array.
So, in your case insert this into the rules array
'world/index' => 'api/index'
You can read more about URL rules here.
also you use ControllerMap
it useful when you are using third-party controllers and you do not have control over their class names.
below code in component in main.php in advance or web.php in basic
for example:
'controllerMap' => [
'api' => 'app\controllers\WorldController',
]

Custom naming in router resources

i have in my controller
public function details($id)
{
$claim = Claim::findOrFail($id);
$details = $claim->details;
return response()->json([], 200);
}
and I have in my routes
Route::resource('claims', 'Admin\\ClaimsController',['names'=> ['details'=>'admin.claims.details'], 'only' => ['index','store','update','destroy','details']]);
when I run php artisan route:list i do not see the admin.claims.details( admin/claims/1/details) in the list
the documentation is pretty vague here so I'm asking how to properly set a custom route? How do I specify if its "POST" or "GET"?
To override the default resource controller actions' route names, you can pass a names array with your options.
For example:
Route::resource('claims', 'ControllerClassName', [
'names' => [
'index' => 'admin.claims.details',
'create' => 'admin.claims.create',
// etc...
],
'only' => [
'index','store','update','destroy','details'
]
]);
REF: https://laravel.com/docs/5.2/controllers#restful-naming-resource-routes
Here are examples of setting custom named get/post routes.
GET Route
Route::get('claims', ['as' => 'admin.claims.details', uses => 'ControllerClassName']);
POST Route
Route::post('claims', ['as' => 'admin.claims.details', uses => 'ControllerClassName']);
REF: https://laravel.com/docs/5.2/routing#named-routes

Laravel 5 - Kodeine ACL using custom resource method inside route protection

I'm a newbie to Laravel. I am using Kodeine ACL management for Laravel 5. Generated resourceful controllers and routes. I also added custom method for resourceful controller named "profile"
I am not able to apply ACL if I include custom method if I do this:
Route::get('users/profile', UsersController#profile);
Route::group(['middleware' => ['auth', 'acl'],
'is' => 'worker',
'protect_alias' => 'worker.user',
'protect_methods' => [
'create' => ['create', 'store'],
'store' => ['create', 'store'],
'read' => ['index', 'show'],
'view' => ['index', 'show'],
'edit' => ['edit', 'update', 'profile'],
'update' => ['edit', 'update', 'profile'],
'delete' => ['destroy'],
]
],
function () {
Route::resource('users', 'UsersController');
});
The above code does not applying the ACL to profile method
But if I comment line #1, it applies the ACL, but it is not directing to the profile method [ie $next($request)] doesn't seem to work
Please advise if I am wrong and how to achieve this.
Thanks!

Resources