Generate well formed routes from MenuBuilder class in Symfony2 - php

I've this route defined in a controller:
/**
* #Secure(roles="IS_AUTHENTICATED_FULLY")
* #Route(
* "/proccess/{slug}",
* requirements={"slug": "^([a-zA-Z0-9]*-[a-zA-Z0-9]*)+$"},
* name="registerRPNI"
* )
*/
public function indexAction(Request $request)
{
......
}
And I need to set the right route in KNPMenuBundle MenuBuilder class. I'm doing as follow:
->addChild('Process RPNI', array(
'uri' => '/process/national-and-imported-products-registration',
))
And it works for dev environment since route shows the right page and execute the right code but if I move away from dev and goes live to prod then I got a 404 Not found, what I'm doing wrong in this case? What should be the right way to generate the routes inside the MenuBuilder class? Any advice around this?

Related

Laravel change language via URL/Route

Fairly new to Laravel and I'm trying to add a functionality that allows the user to switch between two languages by clicking a button in a header.blade.php file. So far I've got it so there's a test.php file in the respective lang directories with test strings and have managed to get <p>{{__('test.test')}}</p> to display the correct language when manually set. At the moment I'm not sure if this is actually calling the route to update the language or if the logic I have for updating it is wrong since I get no errors and I'm using barryvdh/laravel-debugbar to debug.
My logic for the button:
<button href="{{ url('language', config('app.locale') == 'en' ? 'fr' : 'en') }}">{{ config('app.locale') }}</button>
In routes/web.php:
Route::get('/language', 'LanguageController#show');
Route::post('/language/{lang}', 'LanguageController#update');
LanguageController.php, created via php artisan make:controller --api
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class LanguageController extends Controller
{
/**
* Display the specified resource.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function show($id)
{
return App::getLocale();
}
/**
* Update the specified resource in storage.
*
* #param \Illuminate\Http\Request $request
* #param int $id
* #return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
//Tried the following
config(['app.locale' => $id]);
App::setlocale($id);
}
}
Questions:
Is this the correct way to update the language at runtime?
How can I tell if my api calls are being made?
How can I achieve this inside of a template .vue file?
Is making a Controller for the language redundant?
Would the inner HTML of my button change if the locale was changed?
Is affecting config files at runtime bad practice?
--Edit--
I should also mention that the only reason I made a controller for this is because I had the route calls in web.php use a function instead however, they stated they were Closure running php artisan route:list and with the research I found I couldn't tell if that was correct
You are on the right way, but there is something missing.
You can't use the configuration to edit at runtime the language.
Save local language in user Session and create a new middleware to set on each request the language saved in session.
I found this article that can help you, localization-laravel

Laravel two 404 styles

I have a main site and an admin control panel.
I want to have different 404 pages for each version.
How should I do this? I currently have the following code in my app/Exceptions/Handles.php file:
/**
* Render an exception into an HTTP response.
*
* #param \Illuminate\Http\Request $request
* #param \Exception $exception
* #return \Illuminate\Http\Response
*/
public function render($request, Exception $exception)
{
if($exception instanceof \Symfony\Component\HttpKernel\Exception\NotFoundHttpException)
{
$view = $request->is('admin/*') ? 'acp.errors.404' : 'errors.404' ;
return response()->view($view, [], 404);
}
return parent::render($request, $exception);
}
But I use the package spatie/laravel-permission and get the following error;
Trying to get property 'role' of non-object (View: F:\Development\RPR\site\resources\views\layouts\acp.blade.php) (View: F:\Development\RPR\site\resources\views\layouts\acp.blade.php)
I use in acp.blade.php auth()->user()->role, to get the user role, which just works fine without any exception. How should I fix this?
Here are two ways to accomplish different 404 views depending on the route. Both will allow you to have these error pages:
/resources/views/acp/errors/404.blade.php
/resources/views/errors/404.blade.php
The directories will be checked in order until a view is found, which means you can selectively add custom error views and fall through to the default when none exist. If the route did not match, then it will not look for a custom error page.
Option 1
Override registerErrorViewPaths() inside app/Exceptions/Handler.php:
/**
* Register the error template hint paths.
*
* #return void
*/
protected function registerErrorViewPaths()
{
parent::registerErrorViewPaths();
if (request()->is('admin/*')) {
View::prependNamespace(
'errors',
realpath(base_path('resources/views/acp/errors'))
);
}
}
Option 2
Create a ViewServiceProvider:
php artisan make:provider ViewServiceProvider
Register your provider in config/app.php:
'providers' => [
// ...
App\Providers\ViewServiceProvider::class,
],
Edit the boot method of your provider:
/**
* Bootstrap services.
*
* #return void
*/
public function boot()
{
if (request()->is('admin/*')) {
View::prependNamespace(
'errors',
realpath(base_path('resources/views/acp/errors'))
);
}
}
For the second part of the question, auth()->user() is only available when the session middleware has run. If the 404 was caused by the route not existing, then the request does not go through the web middleware and unfortunately sessions and auth information will not be available. However, if the 404 was caused by a ModelNotFoundException triggered inside a controller, then the web middleware probably did run and you can access the user.
Inside your error view you have to check if the user is signed in:
#guest
<p>Hello, guest</p>
#else
<p>Hello, {{ auth()->user()->name }}</p>
#endguest
If this is not good enough for your use case, then you might want to try Route::fallback(), which allows you to define a controller for serving 404 pages and does run web middleware.

Route Error: Symfony 4 No route found for "GET /blog"

I am having this error:
Symfony\Component\HttpKernel\Exception\NotFoundHttpException: No route
found for "GET /blog" (from "http://localhost:8000/produits")
I added the annotation #Route in the method in my controller (like I saw in other website):
/**
* #Route("/blog", name="article.index")
* #return Response
* */
public function index():Response
{
return $this->render("blog/article.html.twig", [
"current_menu" => 'articles'
]);
}
I tried to add methods={"GET","HEAD"} in #Route but I have the same error
How do I solve this problem?
This one worked for me (adding / to the end of route path):
/**
* #Route("/blog/", name="article.index")
* #return Response
* */
public function index():Response
{
return $this->render("blog/article.html.twig", [
"current_menu" => 'articles'
]);
}
You will also at least need use Symfony\Component\Routing\Annotation\Route; at the start of the file (among the other 'use' lines), Some framework setup for Route annotations could also need to be enabled. Also, how does blog/article.html.twig refer to the route or path?
A freshly installed Symfony 4 instance will need composer require doctrine/annotations package, unless its already been installed by some other package.
https://symfony.com/doc/current/routing.html#creating-routes has more details.

Laravel 5.7.6 resource route with auth

I'm starting my first Laravel project (first MVC / OOPHP project infact) and could use some help with routes.
I followed the guide at https://medium.com/employbl/easily-build-administrator-login-into-a-laravel-5-app-8a942e4fef37 to add a check if user is admin when loading a page. It works for normal view routes, e.g.
Route::get('/admin/something', 'AdminController#admin_something')
->middleware('is_admin')
->name('admin');
But I now have a resource route and get an error when I add the two -> lines to the route. So this works with no auth:
Route::resource('thingies', 'ThingyController');
But with this:
Route::resource('thingies', 'ThingyController')
->middleware('is_admin')
->name('admin');
I get the error Symfony \ Component \ Debug \ Exception \ FatalThrowableError (E_RECOVERABLE_ERROR)
Too few arguments to function Illuminate\Routing\PendingResourceRegistration::name(), 1 passed in /var/www/routes/web.php on line 24 and exactly 2 expected
What do I need to do differently to add this auth to a resource route?
The is_admin() function from the tutorial:
const ADMIN_TYPE = 'admin';
const DEFAULT_TYPE = 'default';
public function isAdmin() {
return $this->type === self::ADMIN_TYPE;
}
And the middleware:
namespace App\Http\Middleware;
use Closure;
class IsAdmin
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if(auth()->user()->isAdmin()) {
return $next($request);
}
return redirect('home');
}
}
You can't name your route "admin" with ->name('admin'); at the end of your resource route because it concerns all CRUD routes in one statement and Laravel build-in system has already named them.
You're on the good way, just delete the last line like so, it should works :
Route::resource('thingies', 'ThingyController')
->middleware('is_admin');
You cannot give a 'name' to a resource route. but you can give names to each method in the resource controller separately.
to do so name() function required 2 parameters.
method name
name for that method route.
,
Route::resource('thingies', 'ThingyController')
->middleware('is_admin')
->name('create', 'admin.create');

Symfony2 Controller Route clash

Hey all I have a bit of a problem with root annotations in Symfony2.
I have two different controllers that call methods from the same URL positions /test.
Controller 1:
**
* #Route("/test", service="myProject.test.controller.art")
* #Cache(expires="+5 minutes", public=true)
*/
class BlogController
{
/**
* #Route("/{text}", defaults={"text" = null})
* #Route("/topic/{tag}", defaults={"tag" = null})
* #Method({"GET"})
*/
public function listAction(ArtQuery $query)
{
//.................
}
}
Controller 2:
**
* #Route("/test" , service="myProject.test.controller.sitemap"))
* #Cache(expires="+5 minutes", public=true)
*/
class SitemapController
{
/**
* #Route("/sitemap.xml/")
* #Method({"GET"})
*/
public function sitemapAction()
{
//..................
}
}
The problem is that the second Controller is never matched only if is add in my #route("/sitemap.xml/") but I realy want the route to be only #route("/sitemap.xml").
I think the problem is when i input the url /test/sitemap.xml Symfony treats sitemap.xml as /{text} variable route in first controller.
Can I make a exception so that first controller ends as soon as it hits sitemap.xml....?
I read something about requirements but dont quiet understand this concept
The router will use the first route that matches the path.
The only way to prioritize a route over another which could match is to ensure that the stricter requirements are check before the weaker ones.
Normally this would be accomplished by placing the sitemapAction method above listAction.
However since you have a controller for each of these, you will have to put the controllers in the correct order.
To do this you will need to add the controllers to the config individually like this:
app_sitemap:
resource: "#AppBundle/Controller/SitemapController.php"
type: annotation
prefix: /
app_blog:
resource: "#AppBundle/Controller/BlogController.php"
type: annotation
prefix: /
This way the controllers will be iterated in this order.
However it is better if you can give each route a unique path, perhaps:
#Route("/query/{text}", defaults={"text" = null})
according to documentation
Earlier Routes always Win
What this all means is that the order of the routes is very important.
If the blog_show route were placed above the blog route, the URL
/blog/2 would match blog_show instead of blog since the {slug}
parameter of blog_show has no requirements. By using proper ordering
and clever requirements, you can accomplish just about anything.
http://symfony.com/doc/current/book/routing.html
i suggest to use yml or xml file for routing
or you can make a requirement in your first route
/**
* #Route("/{text}", defaults={"text" = null}, requirements={"text" = "^(?!sitemap\.xml)$"})
* #Route("/topic/{tag}", defaults={"tag" = null})
* #Method({"GET"})
*/
public function listAction(ArtQuery $query)
{
//.................
}

Categories