Issue with locales on custom error controller in Symfony - symfony

I overided the default ErrorController by following this guide:
https://symfony.com/doc/current/controller/error_pages.html#overriding-the-default-errorcontroller
Everything works fine, but the error page isn't translated on changing languages (/en, /de).
The locale is always set to default.
How can I fix it?
Thanks in advance.
Here is my error controller (very simplified):
class ErrorController extends AbstractController
{
public function error(FlattenException $exception, Request $request){
$statusCode = $exception->getStatusCode();
return $this->render("error/error{$statusCode}.html.twig", [
]);
}
}

Related

Link to some action of a different CRUD controller

Is there any workaround to link a new action, in a CRUD controller made with EasyAdmin 4.x , to an action in another CRUD controller with which it has a OneToMany relation ?
class FirstEntityCrudController extends AbstractCrudController
{
...
public function configureActions(Actions $actions): Actions
{
return $actions
->add(Crud::PAGE_INDEX, Action::new('add-second-entity','Add a second entity')
->linkToCrudAction(Action::NEW ???)
)
;
}
}
The docs say that I can use:
linkToCrudAction(): to execute some method of the current CRUD controller;
But there seems to be no indication on how to "execute some method of a different CRUD controller".
Note:
There is a sneaky way around it but it doesn't seem healthy :
->linkToUrl('the url to the desired action')
Using:
PHP 8.1
Symfony 5.4
EasyAdmin 4.x
Following #Ruban's comment, and as EasyAdminBundle's docs mention, we can generate a URL for the desired action using the AdminUrlGenerator class as follow:
class FirstEntityCrudController extends AbstractCrudController
{
private $adminUrlGenerator;
public function __construct(AdminUrlGenerator $adminUrlGenerator)
{
$this->adminUrlGenerator = $adminUrlGenerator;
}
...
public function configureActions(Actions $actions): Actions
{
//The magic happens here 👇
$url = $this->adminUrlGenerator
->setController(SecondEntityCrudController::class)
->setAction(Action::NEW)
->generateUrl();
return $actions
//->...
->add(Crud::PAGE_INDEX,
Action::new('add-second-entity', 'Add second entity')
->linkToUrl($url)
);
}
}
This worked for me.

Setting up a framework-only SilverStripe site

I'm looking to create a framework only SilverStripe website, however I have been unable to correctly set up the routing for it.
I want to have a single controller handling a handful of URLs. I want it to handle an empty URL too, i.e. '/'.
I've been unable to get my controller to differentiate between the different urls.
My routes are as follows:
---
Name: rootroutes
---
Director:
rules:
'$Action/$ID/$OtherID': 'MainController'
'': 'MainController'
and my controller:
class MainController extends Controller {
private static $url_handlers = array(
'$Action//$ID/$OtherID' => 'handleAction',
);
public function index() {
return "index";
}
public function login() {
return "login";
}
public function handleAction($request, $action) {
var_dump($action); // always 'index'
if($this->hasMethod($action)) {
return $this->$action();
}
}
}
You need to define the $allowed_actions array on your controller before actions other than index() will work.

Symfony Custom Error Page By Overriding ExceptionController

what I am trying to do is to have custom error page, not only will they be extending the base layout but also I want extra up selling content in those pages too so changing templates only is not an option
regardless of the reason (404 Not Found or just missing variable) I would like to show my template and my content instead
I have spent hours trying to get this going with no luck
app/console --version
Symfony version 2.5.6 - app/dev/debug
I tried some resources, but couldn't get it working. The name a few:
http://symfony.com/doc/current/reference/configuration/twig.html
http://symfony.com/doc/current/cookbook/controller/error_pages.html
I'm running in dev with no debug, see app_dev.php below:
$kernel = new AppKernel('dev', false);
following the tutorials i got these extra bits
app/config/config.yml
twig:
exception_controller: SomethingAppBundle:Exception:show
in my bundle
<?php
namespace Something\AppBundle\Controller;
use Symfony\Component\HttpKernel\Log\DebugLoggerInterface;
use Symfony\Component\HttpKernel\Exception\FlattenException;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class ExceptionController extends Controller
{
public function showAction( FlattenException $error, DebugLoggerInterface $debug)
{
print_r($error);
}
}
but my error controller does not get executed,
I am on purpose causing error by trying to echo undefined variable in different controller, since it should handle error from entire application
At the beginning you need to create action in the controller:
<?php
namespace AppBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class ErrorController extends Controller
{
public function notFoundAction()
{
return $this->render('error/404.html.twig');
}
}
Then you need to create a Listener:
<?php
namespace AppBundle\EventListener;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\HttpKernelInterface;
class NotFoundHttpExceptionListener
{
private $controller_resolver;
private $request_stack;
private $http_kernel;
public function __construct($controller_resolver, $request_stack, $http_kernel)
{
$this->controller_resolver = $controller_resolver;
$this->request_stack = $request_stack;
$this->http_kernel = $http_kernel;
}
public function onKernelException(GetResponseForExceptionEvent $event)
{
if ($event->getException() instanceof NotFoundHttpException) {
$request = new \Symfony\Component\HttpFoundation\Request();
$request->attributes->set('_controller', 'AppBundle:Error:notFound');
$controller = $this->controller_resolver->getController($request);
$path['_controller'] = $controller;
$subRequest = $this->request_stack->getCurrentRequest()->duplicate(array(), null, $path);
$event->setResponse($this->http_kernel->handle($subRequest, HttpKernelInterface::MASTER_REQUEST)); // Simulating "forward" in order to preserve the "Not Found URL"
}
}
}
Now register the service:
#AppBundle/Resources/config/services.yml
services:
kernel.listener.notFoundHttpException:
class: AppBundle\EventListener\NotFoundHttpExceptionListener
tags:
- { name: kernel.event_listener, event: kernel.exception, method: onKernelException, priority: -10 }
arguments: [ #controller_resolver, #request_stack, #http_kernel ]
Not tested this, but rather it should work;)
EDIT:
Tested, it works. On the rendered page, you have a session, so you have access to app.user, his cart, and other matters related to the session.

How return an array from a symfony2 controller action?

in my symfony2 project i need call the same action in many controllers and this action should return a very simple php array that then will be passed to a twig template by these controllers. How can i do it?
A pratical example can explain my situation better.
1.shared controller
// Acme/DemoBundle/Controller/MetasController
class MetasController extends Controller {
public function metasAction() {
$myArray= array();
return $myAarray;
}
}
page render controller
// Acme/DemoBundle/Controller/PageController
class PageController extends Controller {
protected $property = "test";
public function indexAction() {
$metas= $this->forward('AcmeDemoBundle:Metas:metas');
return $this->render('AcmeDemoBundle:Page:index.html.twig', array('property'=>property, 'metas'=>$metas));
}
}
when i do this i get an error: the controller must be a response array given.
You should create a service
// Acme/DemoBundle/Controller/MetasController
class MetasController {
public function metasAction() {
$myArray= array();
return $myAarray;
}
}
declare as service in Acme\DemoBundle\Resources\config\services.yml
services:
demo.metas:
class: "Acme\DemoBundle\Controller\MetasController"
Then you can use it in any other controller
// Acme/DemoBundle/Controller/PageController
class PageController extends Controller {
protected $property = "test";
public function indexAction() {
$metas= $this->get('demo.metas')->metas();
return $this->render('AcmeDemoBundle:Page:index.html.twig', array('property'=>property, 'metas'=>$metas));
}
}
In your action controller :
<?php
...
$arrayExample = array();
return $this->render('ExampleBundle:ExampleFolder:exampleTemplate', array('myArray' => $arrayExample));
And in your twig template now you have access to your array using myArray
Example :
{% for data in myArray %}
...
{% endfor %}
Try this :
use Symfony\Component\HttpFoundation\Response;
public function indexAction()
{
...
$content = $this->renderView(
'AcmeDemoBundle:Page:index.html.twig',
array('property'=> $property,
'metas' => $metas
));
return new Response($content);
}
Yes, you can register your controller as a service as it said above but I would recommend to isolate this logic in a different place. It might be a service but not controller.
As I understand you need the same array in several places. So, it might be some class registered as service or some simple class with static method providing this array. In this case your code will be much cleaner.
If you need this array only in view you can define custom twig method which will return array you need. If this array might be different time to time (if it might depend on some data) you can pass entity manager to the service providing this array or to the twig extension.
(The best use of controllers is to be just a proxy between view and data layer. It's not a good idea to use it for such purposes as you described (in my opinion of course).)

Calling controller inside a controller

Why it gives the following error when calling controller inside a controller?
Fatal error: Call to a member function get() on a non-object in
/home/web/project/symfony2/vendor/symfony/src/Symfony/Bundle/FrameworkBundle/Controller/Controller.php
on line 149
In the controller I called a class that extends Controller:
class DemoController extends Controller
{
public function indexAction()
{
$object = new \Acme\DemoBundle\Service\Object();
$object->method();
}
// ...
}
The class is something like this:
# Acme/DemoBundle/Service/Object.php
class Object extends Controller
{
public function method()
{
$em = $this->getDoctrine()->getEntityManager(); // the problem
// ...
}
}
When I use $this to call service, doctrine, or something else like within a controller, the error occurred. Otherwise, it works.
How can I use, for example, doctrine inside this class?
Try
$object->setContainer($this->container);
before you call method()
Edit:
Basically it's a bad idea to have a service extend Controller but if you really need to do this, try to add this
your.service:
class: Your\Class
arguments: [...]
calls:
- [ setContainer, [#service_container] ]
in your service configuration file (probably service.yml)

Resources