I recently put my project into production. And since then I can no longer create, edit and delete. I am automatically redirected to my dashboard and in my console log I have a 406 error (Not Acceptable)
Especially since I had no problem when I was local.
Thank you in advance for your help
I am using EasyAdmin version 4.4 and Symfony 6.0
<?php
namespace App\Controller\Admin;
use App\Entity\User;
use App\Entity\Skills;
use App\Entity\Project;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use EasyCorp\Bundle\EasyAdminBundle\Config\MenuItem;
use EasyCorp\Bundle\EasyAdminBundle\Config\Dashboard;
use EasyCorp\Bundle\EasyAdminBundle\Router\AdminUrlGenerator;
use EasyCorp\Bundle\EasyAdminBundle\Provider\AdminContextProvider;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractDashboardController;
class DashboardController extends AbstractDashboardController
{
private $adminContextProvider;
public function __construct(AdminContextProvider $adminContextProvider)
{
$this->adminContextProvider = $adminContextProvider;
}
#[Route('/admin', name: 'admin')]
public function index(): Response
{
return $this->render('admin/dashboard.html.twig');
}
public function configureDashboard(): Dashboard
{
return Dashboard::new()
->setTitle('My Project');
}
public function configureMenuItems(): iterable
{
yield MenuItem::linktoRoute('Back to the website', 'fa-solid fa-rotate-left', 'app_home');
yield MenuItem::linkToDashboard('Dashboard', 'fa fa-home');
yield MenuItem::linkToCrud('Profil', 'fas fa-user', User::class);
yield MenuItem::linkToCrud('Projects', 'fas fa-list', Project::class);
yield MenuItem::linkToCrud('Skills', 'fa-solid fa-gears', Skills::class);
}
}
Related
We're building a REST API in Symfony and in many Controllers we're repeating the same code for parsing and settings properties of objects/entities such as this:
$title = $request->request->get('title');
if (isset($title)) {
$titleObj = $solution->getTitle();
$titleObj->setTranslation($language, $title);
$solution->setTitle($titleObj);
}
I'm aware that Symfony forms provide this functionality, however, we've decided in the company that we want to move away from Symfony forms and want to use something simplier and more customisable instead.
Could anybody please provide any ideas or examples of libraries that might achieve property parsing and settings to an object/entity? Thank you!
It seems like a good use case for ParamConverter. Basically it allows you, by using #ParamConverter annotation to convert params which are coming into your controller into anything you want, so you might just create ParamConverter with code which is repeated in many controllers and have it in one place. Then, when using ParamConverter your controller will receive your entity/object as a parameter.
class ExampleParamConverter implements ParamConverterInterface
{
public function apply(Request $request, ParamConverter $configuration)
{
//put any code you want here
$title = $request->request->get('title');
if (isset($title)) {
$titleObj = $solution->getTitle();
$titleObj->setTranslation($language, $title);
$solution->setTitle($titleObj);
}
//now you are setting object which will be injected into controller action
$request->attributes->set($configuration->getName(), $solution);
return true;
}
public function supports(ParamConverter $configuration)
{
return true;
}
}
And in controller:
/**
* #ParamConverter("exampleParamConverter", converter="your_converter")
*/
public function action(Entity $entity)
{
//you have your object available
}
I am currently migrating an existent application to Symfony2 that has about 100 controllers with approximately 8 actions in each controller. All the current Actions are named as follow:
public function index(){}
However the default naming convention for Symfony is indexAction().
Is it possible to keep all my current actions and tell Symfony to use as it is without the "Action" word after the method name?
thank you.
Yes, this is possible. You should be able to define routes as normal, but you need to change the way the kernel finds the controller. The best way to do this is to replace/decorate/extends the service 'controller_name_converter'. This is a private service and is injected into the 'controller_resolver' service.
The source code of the class you want to replace is at 'Symfony\Bundle\FrameworkBundle\Controller\ControllerNameParser'.
Basically, the code runs like this. The 'bundle:controller:action' you specified when creating the route is saved in the cache. When a route is matched, that string is given back to the kernel, which in turn calls 'controller_resolver' which calls 'controller_name_resolver'. This class convert the string into a "namespace::method" notation.
Take a look at decorating services to get an idea of how to do it.
Here is an untested class you can work with
class ActionlessNameParser
{
protected $parser;
public function __construct(ControllerNameParser $parser)
{
$this->parser = $parser;
}
public function parse($controller)
{
if (3 === count($parts = explode(':', $controller))) {
list($bundle, $controller, $action) = $parts;
$controller = str_replace('/', '\\', $controller);
try {
// this throws an exception if there is no such bundle
$allBundles = $this->kernel->getBundle($bundle, false);
} catch (\InvalidArgumentException $e) {
return $this->parser->parse($controller);
}
foreach ($allBundles as $b) {
$try = $b->getNamespace().'\\Controller\\'.$controller.'Controller';
if (class_exists($try)) {
// You can also try testing if the action method exists.
return $try.'::'.$action;
}
}
}
return $this->parser->parse($controller);
}
public function build($controller)
{
return $this->parser->build($controller);
}
}
And replace the original service like:
actionless_name_parser:
public: false
class: My\Namespace\ActionlessNameParser
decorates: controller_name_converter
arguments: ["#actionless_name_parser.inner"]
Apparently the Action suffix is here to distinguish between internal methods and methods that are mapped to routes. (According to this question).
The best way to know for sure is to try.
// src/AppBundle/Controller/HelloController.php
namespace AppBundle\Controller;
use Symfony\Component\HttpFoundation\Response;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
class HelloController
{
/**
* #Route("/hello/{name}", name="hello")
*/
public function indexAction($name)
{
return new Response('<html><body>Hello '.$name.'!</body></html>');
}
}
Try to remove the Action from the method name and see what happens.
I know this is no doubt a simple answer, but I just cannot seem to find the answer. I'm following a course online and this is the custom Controller:
<?php
namespace Drupal\dino_roar\Controller;
use Drupal\dino_roar\Jurrasic\RoarGenerator;
use Symfony\Component\HttpFoundation\Response;
class RoarController
{
public function roar($count)
{
$test = new RoarGenerator();
return new Response('hello');
}
}
This is the object:
<?php
namespace Drupal\dino_roar\Jurrasic;
class RoarGenerator
{
public function getRoar($length)
{
return 'R' . str_repeat('O', $length) . 'AAARRR';
}
}
But, I keep getting this:
Fatal error: Class 'Drupal\dino_roar\Jurrasic\RoarGenerator' not found
Does anybody have any ideas?
Also, I know Jurassic is spelt wrong :S
Hello I dont know how to fix this bug , I searched in google but I got no solution for this bug, i am just trying to follow this tutorial http://tutorial.symblog.co.uk/docs/validators-and-forms.html, any help will be appreciated
ClassNotFoundException: Attempted to load class "Enquiry" from namespace
"Blogger\BlogBundle\Entity" in
C:\wamp\www\symblog.dev\src\Blogger\BlogBundle\Controller\PageController.php line 22.
Do you need to "use" it from another namespace?
this is the file code:
<?php
// src/Blogger/BlogBundle/Controller/PageController.php
namespace Blogger\BlogBundle\Controller;
// Import new namespaces
use Blogger\BlogBundle\Entity\Enquiry;
use Blogger\BlogBundle\Form\EnquiryType;
class PageController extends Controller
{
public function indexAction()
{
return $this->render('BloggerBlogBundle:Page:index.html.twig');
}
public function aboutAction()
{
return $this->render('BloggerBlogBundle:Page:about.html.twig');
}
public function contactAction()
{
$enquiry = new Enquiry();
$form = $this->createForm(new EnquiryType(), $enquiry);
$request = $this->getRequest();
if ($request->getMethod() == 'POST') {
$form->bindRequest($request);
if ($form->isValid()) {
// Perform some action, such as sending an email
// Redirect - This is important to prevent users re-posting
// the form if they refresh the page
return $this->redirect($this->generateUrl('BloggerBlogBundle_contact'));
}
}
return $this->render('BloggerBlogBundle:Page:contact.html.twig', array('form' => $form->createView()
));
}
}
Make sure:
1 the name of your file is Enquiry.php
2 it is in the folder Blogger/BlogBundle/Entity
3 it is called class Enquiry
4 the namespace is namespace Blogger\BlogBundle\Entity;
Note: The reason is that this is very often due to a typo in either the name of the file, the name of the class, the use statement or the namespace.
I solved it starting PageController.php like this:
<?php
// src/Blogger/BlogBundle/Controller/PageController.php
namespace Blogger\BlogBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Blogger\BlogBundle\Entity\Enquiry;
use Blogger\BlogBundle\Form\EnquiryType;
If you find a better solution, please let me know
If you are sure that your namespaces are all right, check if your PHP file really has .php extension.
I'm using an example of FOSUserBundle with FOSFacebookBundle. Hereon i have build my application.
The relevant Project Structure is like following:
src\ABC\MainBundle\
src\ABC\UserBundle\
src\ABC\MainBundle\Controller\DefaultController.php
src\ABC\UserBundle\Security\User\Provider\FacebookProvider.php
vendor\facebook\php-sdk\src\base_facebook.php
Part of the FacebookProvider:
use \BaseFacebook;
use \FacebookApiException;
class FacebookProvider implements UserProviderInterface
{
protected $facebook;
public function __construct(BaseFacebook $facebook, $userManager, $validator)
{
$this->facebook = $facebook;
}
public function loadUserByUsername($username)
{
try {
$fbdata = $this->facebook->api('/me');
...
As you can see there is the Facebook-Object already available.
What i want to do now is nearly the same, but in my DefaultController:
use \BaseFacebook;
use \FacebookApiException;
class DefaultController extends BaseController
{
public function indexAction(){
$facebook = new Facebook('key', 'secret');
$fbfriends_obj = $facebook->api('/'.$fbid.'/friends');
...
But there i get the message
Fatal error: Class 'ABC\MainBundle\Controller\Facebook' not found in C:\xampp\htdocs\...\src\ABC\MainBundle\Controller\DefaultController.php on line x
Why is that? How can i access the facebook-class from inside my defaultcontroller? If its already possible for the facebookprovider, why it aint possible for my controller?
any hints will be really appreciated!
The solution to that problem is, that the facebook-class has no namespace and you have to do something like
$facebook = new \Facebook(...)
Problem is here:
use \BaseFacebook;
use \FacebookApiException;
You are importing BaseFacebook class from namespace you should use \Facebook (in Controller and FacebookProvider classes)