We're currently working on a Laravel 5 project that hosts separate sub-websites. These separate websites are grouped in the routes and share common prefixes. For example:
Route::group(['prefix' => 'siteone', 'namespace' => 'SiteOneNamespace'], function() {
Route::get('routeone', 'SiteOneController#index');
Route::get('routetwo', 'SiteOneController#indextwo');
(...)
}
Route::group(['prefix' => 'sitetwo', 'namespace' => 'SiteTwoNamespace'], function() {
Route::get('routeone', 'SiteTwoController#index');
Route::get('routetwo', 'SiteTwoController#indextwo');
(...)
}
A third party library is used by all sites in this project. This third party library relies on PHP constants for its settings. However, not all sub-sites will have the same settings, as some of the settings will differ depending on each site.
So my question is: Is there a way that I can define these constants based on the 'prefix' value of each sub-site route, in a way that these constants will be available in the controllers?
Something like:
$routePrefix = getRoutePrefix();
if($routePrefix == 'siteone') {
define("LIBRARY_SETTING", "value_for_site_one");
}
elseif($routePrefix == 'sitetwo') {
define("LIBRARY_SETTING", "value_for_site_two");
}
I know that we can probably do this in the routes.php file, but I think there must be a more elegant solution for this, as the routes file isn't supposed to be a place to define constants. I appreciate any input.
You can do it in a middleware:
namespace App\Http\Middleware;
use Closure;
class CreateConstant
{
public function handle($request, Closure $next, $name, $value)
{
define($name, $value);
return $next($request);
}
}
Then register it in the App\Http\Kernel class:
protected $routeMiddleware = [
// other route middleware...
'constant' => 'App\Http\Middleware\CreateConstant',
];
Finally, use it on your route groups:
Route::group([
'prefix' => 'siteone',
'namespace' => 'SiteOneNamespace',
'middleware' => 'constant:LIBRARY_SETTING,value_1',
], function() {
// routes
});
Route::group([
'prefix' => 'sitetwo',
'namespace' => 'SiteTwoNamespace',
'middleware' => 'constant:LIBRARY_SETTING,value_2',
], function() {
// routes
});
Related
I'm trying to have access to {module} inside my function, but it returns me the following error :
Too few arguments to function {closure}(), 1 passed in /Users/Bernard/PROJECTS/myproject/vendor/laravel/lumen-framework/src/Routing/Router.php on line 62 and exactly 2 expected
Here's my code :
$app->router->group([
'namespace' => 'App\Http\Controllers',
], function ($router) {
$router->group([
'namespace' => $version,
'prefix' => "api/$version/{contest}/{module}",
'middleware' => 'App\Http\Middleware\COMMON\DefineContest',
], function ($request, $module) use ($router) {
dd($module);
require __DIR__ . "/../routes/v1/{module}.routes.php";
});
});
In Laravel, it would be as simple as calling Illuminate\Support\Facades\Route::parameter(paramname) but since it is apparently not available in Lumen(looking at Lumen Router there are no methods or parameters for this use case), this is an imperative answer that does get the job done:
$version = 1;
$router->group([
'namespace' => 'App\Http\Controllers',
], function ($router) use ($version) {
$router->group([
'namespace' => $version,
'prefix' => "api/$version/{contest}/{module}",
'middleware' => 'App\Http\Middleware\COMMON\DefineContest'
], function ($router) use ($version) {
$url = $_SERVER['REQUEST_URI'];
if (preg_match("/api\/$version\/(?<contest>\w+)\/(?<module>\w+)/", $url, $output)) {
$module = $output['module'];
dd($module);
}
});
});
I should point out that this code results in an extra step for every route which I don't think matters since it's not that heavy but something to note of.
I've run into a problem with the updated version of Laravel and the new routing.
The route with the resources works just fine and uses the correct namespace, the problem is with the direct route "users/table", it's not using any namespace and returns "Target class [UserController] does not exist."
.
When I apply the full controller namespace and class name it works. I've modified my RouteResourceProvider.php and it's loading the default namespace on boot.
My question is why the resources method works but for the custom route, I have to specify the entire namespace inside the route group with an already set namespace?
Route::group(['prefix' => 'admin', 'as' => 'admin.', 'namespace' => 'Admin'], function () {
Route::post('users/table', [UserController::class, 'table']);
...
Route::resources([
'users' => UserController::class,
...
]);
});
Route::group(['prefix' => 'admin', 'as' => 'admin.', 'namespace' => 'App\Http\Controllers\Admin'], function () {
Route::post('users/table', [UserController::class, 'table']);
...
Route::resources([
'users' => UserController::class,
...
]);});
I have guard 'admin'.
how I know in Laraver guard work as multi auth(I can log in as a user and as Admin at once).
but I pretty surprise when I have an error about ERR_TOO_MANY_REDIRECTS when I log in as admin and try to check the page with auth middleware. Like admin this si no auth user no auth?
Have code like this
Route::group([ 'namespace' => 'Shop','middleware' => ['auth'], 'prefix' => 'shop'], function () {
Route::get('/', 'MainController#index')->name('shop');
Route::get('/search', 'MainController#search')->name('shop.search');
Route::get('/ajax-search', 'MainController#ajaxSearch')->name('shop.ajax-search');
Route::get('autocomplete', 'MainController#autocomplete')->name('shop.autocomplete');
Route::get('/searchbyname', 'MainController#searchbyname')->name('shop.searchbyname');
});
Route::group(['prefix' => 'cart','middleware' => ['auth:admin'], 'namespace' => 'Shop'], function () {
Route::get('/','CartController#index')->name('shop.cart');
Route::get('/add','CartController#add')->name('cart.add');
Route::get('/details','CartController#details')->name('cart.details');
Route::delete('/{id}','CartController#delete')->name('cart.delete');
});
how I can resolve this issue if I wanna that admin has all access as Authentication user + admin routes?
You can declare 2 middlewares in the Route::group. E.g.:
Route::group([ 'namespace' => 'Shop','middleware' => ['auth', 'auth:admin'], 'prefix' => 'shop'], function () {
...
});
maybe this helps you
Route::get('/', function () {
...})->middleware('first', 'second');
multiple middleware to the route
I have created ApiController in App\Http\Controllers\Api\v1
Also created auth using laravel/ui
Default created function for front end working perfectly.
But issue is when try to call the ApiController
My API Route file is as below
Route::group(['prefix' => 'api/v1', 'namespace' => 'Api\v1'], function () {
Route::post('register', 'ApiController#register');
});
And my API controller look like
namespace App\Http\Controllers\Api\v1;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class ApiController extends Controller
{
public function register(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
'api_token' => Str::random(60),
]);
}
}
Before 404 it was csrf error and i have resolving it by
protected $except = [
'/register',
];
in Http\Middleware\VerifyCsrfToken
I cant figure out two question
How to except my entire api call from CSRF using $except..
How to solve 404 for register method , i use postman with POST request and call URL http://localhost/larablog/api/v1/register
Routes defined in the routes/api.php file are nested within a route group by the RouteServiceProvider. Within this group, the /api URI prefix is automatically applied so you do not need to manually apply it to every route in the file. You may modify the prefix and other route group options by modifying your RouteServiceProvider class.
1) 404 error :- Remove api from prefix route.
Route::group(['prefix' => 'v1', 'namespace' => 'Api\v1'], function () {
Route::post('register', 'ApiController#register');
});
http://localhost/larablog/api/v1/register
1. If you are using a route group:
Route::group(['prefix' => 'v1', 'namespace' => 'Api\v1'], function () {
Route::post('register', 'ApiController#register');
});
Your $except array looks like:
protected $except = ['v1/register'];
2. If you want to exclude all routes under v1
Your $except array looks like:
protected $except = ['v1/*'];
I've read that it's possible to specify namespace for Dingo in that way
$api = app('Dingo\Api\Routing\Router');
$api->version('v1', ['namespace' => 'App\Http\Controllers'], function ($api) {
$api->get('sites', 'SiteController#index');
$api->get('sites/{site}', 'SiteController#show');
$api->post('sites', 'SiteController#store');
$api->put('sites/{site}', 'SiteController#update');
$api->delete('sites/{site}', 'SiteController#delete');
});
However, I've got multiple files with API routes so that I don't want to mess it with namespace and would like to specify namespace in Laravel way like that
protected function mapDingoApiRoutes() {
Route::group([
'middleware' => 'api',
'namespace' => $this->namespace,
], function ($api) {
require base_path('routes/api/sites.api.php');
require base_path('routes/api/skills.api.php');
require base_path('routes/api/socials.api.php');
});
}
However it turned out that Dingo doesn't see this namespace declaration and I'm not able to make something like $api->group()
Solved that way
...
use Dingo\Api\Routing\Router;
class RouteServiceProvider extends ServiceProvider
{
...
public function map()
{
$this->mapDingoApiRoutes(app('Dingo\Api\Routing\Router'));
$this->mapWebRoutes();
}
protected function mapDingoApiRoutes(Router $api) {
$api->group([
'version' => 1,
'middleware' => 'api',
'namespace' => $this->namespace,
], function ($api) {
require base_path('routes/api/sites.api.php');
require base_path('routes/api/skills.api.php');
require base_path('routes/api/socials.api.php');
});
}
...
}