How can I categorise routes in Slim Framework?
I have these basic/ front routes in my public dir,
$app->get('/about', function () use ($app, $log) {
echo "<h1>About ", $app->config('name'), "</h1>";
});
$app->get('/admin', function () use ($app, $log) {
echo 'admin area';
require dirname(__FILE__) . '/../src/Admin/index.php';
});
// To generic
$app->get('/', function () use ($app, $log) {
echo '<h1>Welcome to ', $app->config('name'), '</h1>';
});
// Important: run the app ;)
$app->run();
As you can see that when the route is on /admin, it will load the index.php in Admin directory.
Admin/index.php,
// API group
$app->group('/admin', function () use ($app) {
// Contact group
$app->group('/contact', function () use ($app) {
// Get contact with ID
$app->get('/contacts', function () {
echo 'list of contacts';
});
// Get contact with ID
$app->get('/contacts/:id', function ($id) {
echo 'get contact of ' . $id;
});
// Update contact with ID
$app->put('/contacts/:id', function ($id) {
echo 'update contact of ' . $id;
});
// Delete contact with ID
$app->delete('/contacts/:id', function ($id) {
echo 'delete contact of ' . $id;
});
});
// Article group
$app->group('/article', function () use ($app) {
// Get article with ID
$app->get('/articles', function () {
echo 'list of articles';
});
// Get article with ID
$app->get('/articles/:id', function ($id) {
echo 'get article of ' . $id;
});
// Update article with ID
$app->put('/articles/:id', function ($id) {
echo 'update article of ' . $id;
});
// Delete article with ID
$app->delete('/articles/:id', function ($id) {
echo 'delete contact of ' . $id;
});
});
});
Let's say I have article, contact, etc modules in my admin area. In each of these modules I have routes for get, put, delete. So I group them by module as in Admin/index.php. But I get 404 page not found, when I request these modules on my url, for instance http://{localhost}/admin/contact I should get list of articles on my browser but I get a 404.
I don't have this problem if I put the grouped routes in public/index.php but I don't want to clutter this index as in time I have more modules to add in. I prefer splitting the routes into different indexes.
So is it possible to split the grouped routes into different index.php in different locations (directories).
Or maybe this is not how I should do it in Slim? if so, what is Slim's way for solving this problem?
In your code /admin/contact is the group for the routes that handle the contacts' GET/PUT/DELETE
// see here v
$app->group('/contact', function () use ($app) {}):
If you want to have a route with this URL segment then you should replace group with get
maybe you can remove the groups within the admin
// API group
$app->group('/admin', function () use ($app) {
// Contact group
// $app->group('/contact', function () use ($app) {
// Get All Contacts
$app->get('/contacts', function () {
echo 'list of contacts';
});
// Get contact with ID
$app->get('/contacts/:id', function ($id) {
echo 'get contact of ' . $id;
});
// Update contact with ID
$app->put('/contacts/:id', function ($id) {
echo 'update contact of ' . $id;
});
// Delete contact with ID
$app->delete('/contacts/:id', function ($id) {
echo 'delete contact of ' . $id;
});
// });
});
Then you can access the routes as follow
Get All -> admin/contacts
Get One -> admin/contacts/:id
Update -> admin/contacts/:id
Related
I have a project which have multiple subdomains.
for example I have a subdomain for Students which goes to a student controller and it looks like this:
Route::domain('students.domain.test')->group(function () {
Route::get('/', function () {
return "done reaching the students page";
});
});
The second type of domains is "domain.test" and any subdomain which I'm checking in the request level and that's fine too.
Route::get('/', [HomeController::class, 'index'])->name('index');
But before the second type of domains I want to make subdomain for specific types of Entities which I have in the database.
Route::domain('{someTypes}.domain.test')
->group(function () {
Route::get('/', function () {
return "done reaching SomeTypes Page";
});
});
My Entity table have these attributes: Id, Title, Type "which I want to check if the type is 5".
I tried to use the middleware:
public function handle($request, Closure $next, ...$types)
{
$currentEntity = app('current_entity');
if ($currentEntity->entityType()->whereIn('title->en', $types)->exists()) {
return $next($request);
}
abort(404, 'Sorry, Request Not Found');
}
and I applied it to my routes like this:
Route::group([
'middleware' => ['type:journal']
],function () {
Route::get('/', function(){
return 'journals logic goes here';
});
});
and I have another middleware to ignore types like this:
public function handle($request, Closure $next, ...$types)
{
$currentEntity = app('current_entity');
if ($currentEntity->entityType()->whereIn('title->en', $types)->exists()) {
abort(404, 'Sorry, Request Not Found');
}
return $next($request);
}
and applied it to the other routes like this:
Route::group([
'middleware' => ['except_entity:journal']
], function(){
Route::get('/', function(){
return 'default pages when journals fails';
})->name('index');
I hope its clear what I'm trying to achieve.
First, you need a check what version laravel that you used?
You need to use Middleware. And I think, method to code with laravel 6, 7, or 8, is a little bit different.
Can you give us more information about your code, so we can help it easier?
I have a Route as below that will display a profile depending on the data in the url:
Route::get('/{region}/{summonername}', function () {
return 'Summoner Profile';
});
I have a Form on the Home page which consists of a Input Box and Region Selector. I am posting this data to:
Route::post('/summoner/data');
The problem is that i don't know how i can convert the form data eg. Summoner Name and Region into the url format where the user will be displayed with the profile page and the url would be /{region}/{summonername}. Am i supposed to use a Redirect::to inside my controller? I feel like that is a crappy way of doing it. Any Suggestions?
Right now when i post the data the url displays as '/summoner/data'.
I hope this makes sense, let me know if you need more clarification.
Routes :
Route::post('/summoner/data','ControllerName#FunctionName');
Route::get('/{region}/{summonername}', function () {
return view('SummonerProfile');
});
Controller:
public function FunctionName()
{
$SummonerName = Input::get('SummonerName');
$Region = Input::get('Region');
return Redirect::to('/{$Region}/{$SummonerName}');
}
Hope this will work. Try it!
Using Routes:
Route::post('/summoner/data',function () {
$SummonerName = Input::get('SummonerName');
$Region = Input::get('Region');
return Redirect::to('/{'.$Region.'}/{'.$SummonerName.'}');
});
Route::get('/{region}/{summonername}', function () {
return view('SummonerProfile');
});
Yes, you will need to redirect:
Route::post('/summoner/data', function (Request $request) {
return redirect()->url($request->region .'/'. $request->summonername);
});
If you want to take the data from URL, just do the following
use Illuminate\Http\Request;
Route::post('/summoner/data', function (Request $request) {
echo $request->segment(1); // gives summoner
echo $request->segment(2); // gives data
});
It's just since I started to discover slim and I ran into a problem, I do not know how to look for a solution because it is very strange.
Basically if I declare a function that is called from the route after another function is also called by a route, the first is not performed.
API group
// API group
$app->group('/api/:key', function () use ($app) {
//print all route
$app->get('/all',function () use($app){
echoRoutes();
});
// Library group
$app->group('/themer', function () use ($app) {
//get number of subscribed themer
$app->get('/count','allowed',function (){
echo "ciao";
});
//get information about the themer selected
$app->get('/:id','getThemer'); //AFTER THIS ROUTES /ciao AND /themes NOT WORK
$app->get('/ciao',function () use($app){
echoRoutes();
});
// Get book with ID
$app->get('/themes', function () use ($app) {
$articles = R::findAll('users');
$app->response()->header('Content-Type', 'application/json');
echo json_encode(R::exportAll($articles));
});
//get number of submitted theme by themer
//$app->get('/:id/themes','getSubmitedThemeById');
//get information about selected theme
//$app->get('/:id/themes/:theme','getThemeById');
$app->get('/themes/:id/', function ($id) {
$articles = R::find("users","id = ?",[$id]);
echo json_encode(R::exportAll($articles));
});
});
});
external file with function
//external file with function
function getThemer($key,$id) {
$themer = R::find("themers","id = ?",[$id]);
echo json_encode(R::exportAll($themer));
return true;
}
function countThemer(){
echo "count";
$count = R::exec( 'SELECT COUNT(id) FROM themers' );
echo $count;
}
function allowed($key){
$app = \Slim\Slim::getInstance();
$params = $app->router()->getCurrentRoute()->getParams();
if(!($params["key"]=="giulio"))
$app->redirect ("http://google.com");
}
after the route index.php/api/giulio/themer/1 that call getThemer and work the route index.php/api/giulio/themer/ciao and index.php/api/giulio/themer/themes not work
I thank you in advance for possible help
criticism or comments on the code in 'general appearance are welcome
Change the order of the routes:
// API group
$app->group('/api/:key', function () use ($app) {
//print all route
$app->get('/all',function () use($app){
echoRoutes();
});
// Library group
$app->group('/themer', function () use ($app) {
//get number of subscribed themer
$app->get('/count','allowed',function (){
echo "ciao";
});
$app->get('/ciao',function () use($app){
echoRoutes();
});
// Get book with ID
$app->get('/themes', function () use ($app) {
$articles = R::findAll('users');
$app->response()->header('Content-Type', 'application/json');
echo json_encode(R::exportAll($articles));
});
//get number of submitted theme by themer
//$app->get('/:id/themes','getSubmitedThemeById');
//get information about selected theme
//$app->get('/:id/themes/:theme','getThemeById');
$app->get('/themes/:id/', function ($id) {
$articles = R::find("users","id = ?",[$id]);
echo json_encode(R::exportAll($articles));
});
//get information about the themer selected
$app->get('/:id','getThemer');
});
});
In Laravel, I want to have two different routes that have the same URL, but that runs a different controller based upon the datatype of the input. For example:
Route::get('/name/{id}/', function($id)
{
return 'id is an int:' . $id;
})->where('id', '[0-9]+');
Route::get('/name/{id}/', function($id)
{
return 'id is a string: ' . $id;
})->where('id', '[a-z]+');
This doesn't seem to work, though - the second route seems to overwrite the first completely, so the app wouldn't support ids that were integers. How do you actually accomplish this in Laravel without doing the checking manually inside the route?
Thanks
To not overwrite the first route, use different parameter name
Route::get('/name/{id}/', function($id)
{
return 'id is an int:' . $id;
})->where('id', '[0-9]+');
Route::get('/name/{stringId}/', function($id)
{
return 'id is a string: ' . $id;
})->where('stringId', '[a-z]+');
I think you can seperate this two routing mechanish from each other.
Route::get('user/{id}', function($id)
{
//
})
->where('id', '[A-Za-z]+');
Route::get('user/{id}', function($id)
{
})
->where('id', '[0-9]+');
This code sample from Laravel site. If you want seperate logic more than that you can use filter.
Filter sample:
Route::filter('foo', function()
{
if (Route::input('id') == 1)
{
//
}
});
I hope i can help you.
I have read as many posts as possible, but none of them can solve my problem.
The route:
Route::model('user', 'User');
Route::group(array('prefix' => 'admin'), function() {
Route::get('users/force-delete/{user}', array(
'as' => 'admin-users-force-delete',
'uses' => 'AdminController#handleUserForceDelete'
));
});
The html:
<li>Force Delete</li>
The handler:
public function handleUserForceDelete(User $user)
{
$username_tmp = $user->username;
$message = 'Success! User ' . $username_tmp . ' has been deleted.';
if($user->trashed())
{
$user->forceDelete();
return Redirect::action('AdminController#showUsers')->with('message', $message);
} else {
return Redirect::action('AdminController#showUsers')->with('message', 'User deletion error! Please try again!');
}
}
I tried to put delete and force-delete at the same handler, and the delete action took place but force-delete generated NotFoundHttpException. So I guess the problem is from the force-delete action??
I solved it!
For anyone with the same trouble, soft deleted user(or anything) will not generate an instance passed to the handler (or closure). Therefore, for this case I manually create an instance.
So instead of using this:
//will not handle soft deleted model.
Route::model('user', 'User');
Use this:
Route::bind('user', function($value, $route)
{
return User::withTrashed()->where('id', '=', $value)->first();
});